PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 3.7.1
AI Engine – The Chatbot, AI Framework & MCP for WordPress v3.7.1
3.7.2 3.7.1 3.7.0 3.6.9 3.6.8 3.6.7 3.6.6 3.6.4 3.6.5 3.6.3 3.6.2 3.6.1 3.6.0 3.5.9 3.5.8 3.5.7 3.5.6 3.5.5 3.5.4 3.5.3 3.5.2 3.5.1 3.5.0 3.4.9 3.4.8 3.4.7 0.2.1 1.6.91 0.2.2 1.6.92 0.2.3 1.6.93 0.2.4 1.6.94 0.2.5 1.6.95 0.2.6 1.6.96 0.2.7 1.6.97 0.2.8 1.6.98 0.2.9 1.6.99 0.3.0 1.7.0 0.3.1 1.7.1 0.3.2 1.7.2 0.3.3 1.7.3 0.3.4 1.7.4 0.3.5 1.7.5 0.3.6 1.7.6 0.4.0 1.7.7 0.4.1 1.7.8 0.4.2 1.7.9 0.4.3 1.8.0 0.4.4 1.8.1 0.4.5 1.8.2 0.4.6 1.8.3 0.4.7 1.8.4 0.4.8 1.8.5 0.4.9 1.8.6 0.5.0 1.8.7 0.5.1 1.8.8 0.5.2 1.8.9 0.5.3 1.9.0 0.5.4 1.9.1 0.5.5 1.9.2 0.5.6 1.9.3 0.5.7 1.9.4 0.5.8 1.9.5 0.5.9 1.9.6 0.6.0 1.9.7 0.6.1 1.9.8 0.6.2 1.9.81 0.6.3 1.9.82 0.6.4 1.9.83 0.6.5 1.9.84 0.6.6 1.9.85 0.6.7 1.9.86 0.6.8 1.9.87 0.6.9 1.9.88 0.7.0 1.9.89 0.7.1 1.9.90 0.7.2 1.9.91 0.7.3 1.9.92 0.7.4 1.9.93 0.7.5 1.9.94 0.7.6 1.9.95 0.7.7 1.9.96 0.7.8 1.9.97 0.7.9 1.9.98 0.8.0 1.9.99 0.8.1 2.0.0 0.8.2 2.0.1 0.8.3 2.0.2 0.8.4 2.0.3 0.8.5 2.0.4 0.8.6 2.0.5 0.8.7 2.0.6 0.8.8 2.0.7 0.8.9 2.0.8 0.9.0 2.0.9 0.9.2 2.1.0 0.9.3 2.1.1 0.9.4 2.1.2 0.9.5 2.1.3 0.9.6 2.1.4 0.9.7 2.1.5 0.9.8 2.1.6 0.9.81 2.1.7 0.9.82 2.1.8 0.9.83 2.1.9 0.9.84 2.2.0 0.9.85 2.2.1 0.9.86 2.2.2 0.9.87 2.2.3 0.9.88 2.2.4 0.9.89 2.2.5 0.9.9 2.2.51 0.9.91 2.2.52 0.9.92 2.2.53 0.9.93 2.2.54 0.9.94 2.2.56 0.9.95 2.2.57 0.9.96 2.2.6 0.9.97 2.2.60 0.9.98 2.2.61 0.9.99 2.2.62 1.0.0 2.2.63 1.0.01 2.2.70 1.0.1 2.2.80 1.0.2 2.2.81 1.0.3 2.2.90 1.0.4 2.2.91 1.0.5 2.2.92 1.0.6 2.2.93 1.0.7 2.2.94 1.0.8 2.2.95 1.0.9 2.3.0 1.1.0 2.3.1 1.1.1 2.3.2 1.1.2 2.3.3 1.1.3 2.3.4 1.1.4 2.3.5 1.1.5 2.3.6 1.1.6 2.3.7 1.1.7 2.3.8 1.1.8 2.3.9 1.1.9 2.4.0 1.2.0 2.4.1 1.2.1 2.4.2 1.2.2 2.4.3 1.2.21 2.4.4 1.2.3 2.4.5 1.2.30 2.4.6 1.3.0 2.4.7 1.3.1 2.4.8 1.3.2 2.4.9 1.3.3 2.5.0 1.3.31 2.5.1 1.3.32 2.5.2 1.3.33 2.5.3 1.3.34 2.5.4 1.3.35 2.5.5 1.3.36 2.5.6 1.3.37 2.5.7 1.3.38 2.5.8 1.3.39 2.5.9 1.3.40 2.6.0 1.3.41 2.6.1 1.3.42 2.6.2 1.3.43 2.6.3 1.3.44 2.6.5 1.3.45 2.6.6 1.3.46 2.6.7 1.3.47 2.6.8 1.3.48 2.6.9 1.3.49 2.7.0 1.3.50 2.7.1 1.3.51 2.7.2 1.3.52 2.7.3 1.3.53 2.7.4 1.3.54 2.7.5 1.3.56 2.7.6 1.3.57 2.7.7 1.3.58 2.7.8 1.3.59 2.7.9 1.3.60 2.8.0 1.3.61 2.8.1 1.3.62 2.8.2 1.3.63 2.8.3 1.3.64 2.8.4 1.3.65 2.8.5 1.3.66 2.8.6 1.3.67 2.8.7 1.3.68 2.8.8 1.3.69 2.8.9 1.3.70 2.9.0 1.3.71 2.9.1 1.3.72 2.9.2 1.3.73 2.9.3 1.3.74 2.9.4 1.3.75 2.9.5 1.3.76 2.9.6 1.3.77 2.9.7 1.3.78 2.9.8 1.3.79 2.9.9 1.3.80 3.0.0 1.3.81 3.0.1 1.3.82 3.0.2 1.3.83 3.0.3 1.3.84 3.0.4 1.3.85 3.0.5 1.3.86 3.0.6 1.3.87 3.0.7 1.3.88 3.0.8 1.3.89 3.0.9 1.3.90 3.1.0 1.3.91 3.1.1 1.3.92 3.1.2 1.3.93 3.1.3 1.3.94 3.1.4 1.3.95 3.1.5 1.3.96 3.1.6 1.3.97 3.1.7 1.3.98 3.1.8 1.3.99 3.1.9 1.4.0 3.2.0 1.4.1 3.2.1 1.4.2 3.2.2 1.4.3 3.2.3 1.4.4 3.2.4 1.4.5 3.2.5 1.4.6 3.2.6 1.4.7 3.2.7 1.4.8 3.2.8 1.4.9 3.2.9 1.5.0 3.3.0 1.5.1 3.3.1 1.5.2 3.3.2 1.5.3 3.3.3 1.5.4 3.3.4 1.5.5 3.3.5 1.5.6 3.3.6 1.5.7 3.3.7 1.5.8 3.3.8 1.5.9 3.3.9 1.6.0 3.4.0 1.6.1 3.4.1 1.6.2 3.4.2 1.6.3 3.4.3 1.6.5 3.4.4 1.6.51 3.4.5 1.6.52 3.4.6 1.6.53 1.6.54 1.6.55 1.6.56 1.6.57 1.6.58 1.6.59 1.6.60 1.6.61 1.6.62 1.6.63 1.6.64 1.6.65 1.6.66 1.6.67 1.6.68 trunk 1.6.69 0.0.1 1.6.70 0.0.2 1.6.71 0.0.3 1.6.72 0.0.4 1.6.73 0.0.5 1.6.74 0.0.6 1.6.75 0.0.7 1.6.76 0.0.8 1.6.77 0.0.9 1.6.78 0.1.0 1.6.79 0.1.1 1.6.81 0.1.2 1.6.82 0.1.3 1.6.83 0.1.4 1.6.84 0.1.5 1.6.85 0.1.6 1.6.86 0.1.7 1.6.87 0.1.8 1.6.88 0.1.9 1.6.89 0.2.0 1.6.90
ai-engine / notes / STUDY-SETTINGS-STORAGE.md
ai-engine / notes Last commit date
CHANGELOG-PROPOSAL.txt 3 weeks ago QA-LOOP.md 3 weeks ago RELEASE-QA-NIGHT.md 3 weeks ago STUDY-CONSOLIDATION.md 3 weeks ago STUDY-MCP.md 1 week ago STUDY-SETTINGS-STORAGE.md 1 week ago STUDY-WORKSPACE.md 3 weeks ago STUDY-WPAI-LEARNINGS.md 3 weeks ago
STUDY-SETTINGS-STORAGE.md
122 lines
1 # Settings storage: making saves snappier and safer
2
3 Not scheduled. Written 2026-08-03 after a support ticket (Galit, goldlifeaxis.com) where
4 chatbot settings appeared to save and then reverted on refresh. Each stage below is
5 shippable on its own, in order, and each is useful without the ones after it.
6
7 ## Where we are
8
9 Everything lives in a single WordPress option, `mwai_options`, and the REST route
10 `settings/update` **replaces the whole array**. Three consequences:
11
12 - **Last writer wins, silently.** A second admin, or the same admin with an old tab open,
13 saves a stale snapshot over everything. Nobody is told. This is the likely cause of the
14 ticket above: the user did not lose one setting, they lost the environment, the knowledge
15 env and the instructions all at once, which is what a whole-object overwrite looks like.
16 - **The blast radius is the whole configuration**, including API keys. A one-key POST once
17 wiped every environment and key on a test site of ours. If it can catch us, it will catch
18 an integrator.
19 - **It is large.** 559 KB on a normal site. `autoload` is off, so it is not read on every
20 page load, but it is serialized, sent and written in full on every save.
21
22 ## What is actually in those 559 KB
23
24 Measured on a real site, top-level keys by serialized size:
25
26 | Key | Size | Share |
27 |---|---|---|
28 | `ai_engines` | 254 KB | 47% |
29 | `ai_models` | 214 KB | 40% |
30 | `ai_models_usage_daily` | 18 KB | 3% |
31 | `ai_usage_daily` | 17 KB | 3% |
32 | `ai_models_usage` + `ai_usage` | 21 KB | 4% |
33 | everything else (117 keys) | 35 KB | 3% |
34
35 `ai_engines` holds 11 engines, and 252 KB of its 254 KB is the `models` array hanging off
36 each one. `ai_models` is a flat catalog of 430 model definitions. So **about 86% of the
37 settings blob is a model catalogue**, not settings: data we either ship in
38 `constants/models.php` or fetched from a provider and cached here.
39
40 The real user settings are roughly 35 KB. Everything else is cache and counters riding along
41 on every save.
42
43 ## Stage 1: shrink it (biggest win, lowest risk)
44
45 Move the catalogue out of `mwai_options` into its own option(s), rebuilt on demand:
46
47 - `ai_engines[*].models` and `ai_models` move to something like `mwai_models_cache`.
48 - Usage counters (`ai_usage*`, `ai_models_usage*`) move to their own option, or better to a
49 table, since they are append-heavy and have nothing to do with configuration.
50
51 That takes the settings row from ~559 KB to ~35 KB. Saves get roughly 15x smaller, the
52 window for a partial write shrinks with it, and losing the cache costs a refetch rather than
53 a configuration.
54
55 **No REST contract change**, so nothing outside the plugin notices. Do this one first.
56
57 ## Stage 2: merge on write instead of replacing
58
59 `settings/update` should merge the payload into the stored array key by key, so a client can
60 send only what changed.
61
62 - Kills the stale-tab class outright: an old tab that only touches `chatbot_defaults` can no
63 longer erase `ai_envs`.
64 - Makes the REST API safe for integrators, who currently have to read-modify-write the whole
65 object and usually do not know it.
66 - **Compatibility:** a full object must keep working, because that is what every existing
67 client sends. Merging a complete payload is identical to replacing it, so this is
68 backwards-compatible by construction. The only true removal case (a user deleting the last
69 AI environment) needs an explicit signal, for example a `replace: true` flag or an explicit
70 empty array for that key. Decide this before writing code.
71
72 ## Stage 3: refuse stale saves
73
74 Merging fixes the tab that touched a different section. It does not fix two people editing
75 the same section. For that, send a version with the settings:
76
77 - The GET returns a hash of the stored array. The client sends it back on save.
78 - If it does not match what is stored, reject with a clear error and let the UI say "this
79 page is out of date, reload before saving".
80
81 Small, and it turns a silent loss into a visible, understandable refusal.
82
83 ## Stage 4: move credentials out
84
85 `ai_envs` (API keys) into its own option. After stages 1 to 3 this is belt and braces, but it
86 means no settings mishap can ever cost someone their keys, which is the failure people
87 actually remember.
88
89 ## Backups
90
91 Worth doing early, and independently of the rest: keep the last **three** snapshots of
92 `mwai_options`, rotated on write.
93
94 - Write the current value to `mwai_options_backup_1..3` before each save, rotating, all with
95 `autoload` off.
96 - Surface them in Dev Tools: "Restore settings from 2 saves ago", with the timestamp and the
97 size.
98 - Cheap, and it converts an entire class of support ticket ("my settings vanished") into a
99 one-click recovery, whatever the cause. It also derisks stages 1 to 4.
100 - Skip writing a backup when the value is unchanged, so a save that touches nothing does not
101 push the useful history out.
102
103 ## Rules while doing any of this
104
105 - **The REST contract is sacred.** `settings/update` must keep accepting a complete object
106 and behaving as it does today.
107 - **Migrations must be idempotent**, and must not lose data if a site is on an old version,
108 reverts, or runs the migration twice.
109 - **Never write a partial object** from any of our own code paths in the meantime. See the
110 existing rule about this.
111
112 ## How to check it worked
113
114 1. `SELECT LENGTH(option_value), autoload FROM wp_options WHERE option_name = 'mwai_options'`
115 before and after stage 1. Expect roughly 559 KB down to 35 KB on a comparable site.
116 2. **The two-tab test**, which is the whole point: open Settings in two tabs, change the AI
117 environment in tab A and save, change a chatbot default in tab B and save, reload. Today
118 tab A's change is gone. After stage 2 both survive. After stage 3, tab B is told to
119 reload instead of being allowed to clobber.
120 3. Same test with a persistent object cache enabled, since that is a common ingredient in
121 these reports.
122