PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 3.6.4
AI Engine – The Chatbot, AI Framework & MCP for WordPress v3.6.4
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-WORKSPACE.md
ai-engine / notes Last commit date
CHANGELOG-PROPOSAL.txt 2 days ago QA-LOOP.md 2 days ago STUDY-CONSOLIDATION.md 2 days ago STUDY-MCP.md 2 days ago STUDY-WORKSPACE.md 2 days ago STUDY-WPAI-LEARNINGS.md 2 days ago
STUDY-WORKSPACE.md
328 lines
1 # STUDY-WORKSPACE.md — Chatbot polish → Local Knowledge → Workspace
2
3 > **Living task doc.** Born 2026-07-24 from the hands-on chatbot review + Jordy's Workspace vision
4 > ("a real BIG chatbot": full-screen, history on the left, model picker; our own cheap Mammouth AI,
5 > Pro only). Guiding principle from Jordy: **don't make everything overly complicated. Build smart
6 > reusable components, keep the current chatbots light, build Workspace separately on the same
7 > components.** So: polish first, then a refactor/extraction step with heavy testing, then Workspace.
8 > Demand rule applies ([[feedback_demand_driven_features]]): each phase ships user-visible value.
9
10 ## Phase 1 — Chatbot polish (from the 2026-07-24 hands-on review)
11
12 - [x] **Over-limit lockout.** Limits refuse via WP_Error → `Meow_MWAI_RefusedException` → REST returns
13 `overLimit: true` (HTTP 429) → frontend locks the input (same state GDPR uses). Streaming errors now
14 pass refusal messages through instead of the generic "Oops". Demand: wp.org thread "Chat remains
15 active after usage limit is reached". Validated live as guest + smoke run green.
16 - [x] **Config errors gated to editors.** "Chatbot 'x' not found" only renders for `edit_posts`;
17 visitors get '' + error_log. Both shortcode call sites.
18 - [x] **Transient errors not persisted.** `saveMessages` filters `isError`/role error, matching
19 `onCommitDiscussions`.
20 - [x] **Copy button on code blocks.** `pre` override in ChatbotContent.js; hljs-compatible.
21 - [x] **Visitor-friendly default over-limit messages** (constants/init.php; existing sites keep
22 their saved text).
23 - [x] **Image size cap in messages.** Markdown images rendered unconstrained (a logo filled the
24 whole chat viewport). Cap height, click opens full image. (2026-07-24)
25 - [x] **Empty-state hint.** A bot with no startSentence opens as a dead gray box; show a subtle
26 hint in the empty messages area. (2026-07-24)
27 - [ ] **Chatbot Block page silent mount failure.** On ai.nekod.net/sample-page/ the container divs
28 render but no chatbot mounts, no console error. Reproduce with console open, fix. (Suspect:
29 inline-params block + site-wide popup of the same botId on one page.)
30 - [ ] **Emoji download icon + translation error notice**: shipped 08d04199 / bfb7fce5 (2026-07-24).
31 Listed for the record; done.
32
33 ## Phase 2 — Local Knowledge DB (default embeddings env, "zero external services")
34
35 Goal: a new **"Internal (WordPress DB)"** embeddings environment; no Pinecone/Qdrant account needed.
36 Removes the #1 friction on the top Pro conversion driver. Target: default env for new installs once
37 proven.
38
39 - [x] **Tier 1: PHP brute-force cosine.** DONE 2026-07-24: `premium/addons/internal.php`, packed
40 float32 BLOBs in `wp_mwai_local_vectors`, batched scan + wpdb flush. Measured on ai.nekod.net:
41 1.4ms @ 3 vectors, 210ms @ 5,000 (1536 dims). End-to-end proven: smoke-rag chatbot answered a
42 fact that exists only in the local store. Default env for FRESH installs (first in
43 `embeddings_envs` defaults); existing sites unaffected.
44 - [ ] **Dimension control.** Matryoshka truncation option (512/768) to cut storage + CPU 2-3x.
45 - [ ] **Tier 2: MariaDB native VECTOR (11.7+).** Auto-detect; HNSW index, same env type. Optional,
46 later.
47 - [ ] **Hybrid bonus.** Local content column makes keyword (FULLTEXT) + vector RRF fusion trivial;
48 quietly answers the Qdrant hybrid ask (swimgeek) provider-neutrally.
49 - [x] **Smoke coverage.** DONE 2026-07-24: RAGCHAT check in `test-smoke.js` (site-level + `rag`
50 arg) on the smoke-rag fixture bot wired to Internal env intern01. Validated against a simulated
51 dropped-context regression (broken query_vectors → FAIL, restored → PASS).
52 - [x] **UX.** DONE 2026-07-24: "Internal (WordPress DB)" card first in the env chooser (badge
53 "Simplest"), no API key/server fields, info notice instead. Migration: none needed.
54
55 ## Phase 3 — Component refactor + heavy testing (the step BEFORE Workspace)
56
57 Keep current chatbots light; extract reusable pieces Workspace will share. Overlaps consolidation
58 item #7 (ChatbotContext decomposition): this phase funds it.
59
60 - [x] **Inventory pass.** DONE 2026-07-24 (findings below).
61
62 ### Inventory findings (2026-07-24)
63
64 **The coupling is concentrated in ONE file.** `ChatbotContext.js` (1564 lines) is the only heavy
65 provider. Everything else is either already decoupled or a thin display consumer. This is the good case:
66 we extract logic from one file, not untangle a web.
67
68 **Already shared / reusable as-is (no work):**
69 - `helpers.js` — the real network layer (`mwaiFetch`, `mwaiFetchUpload`, `mwaiHandleRes`), zero context,
70 already imported by both contexts. This IS the streaming glue; nothing to extract.
71 - `helpers/tokenManager.js` — nonce singleton, already shared.
72 - `MwaiAPI.js` — the `window.MwaiAPI` singleton + filter/action bus. The bridge the two contexts talk
73 through. Already global.
74 - `ChatbotContent.js` (236), `ChatbotEvents.js` (291), `ChatbotSpinners.js`, `AudioVisualizer.js`
75 pure props-driven, no context. Drop into Workspace directly.
76
77 **The whole history sidebar is already independent.** `DiscussionsContext.js` (415) makes ZERO
78 `useChatbotContext()` calls — it takes a `system` prop (botId, restNonce), hits
79 `mwai-ui/v1/discussions/{list,edit,delete}` itself, and reaches the chatbot only via
80 `MwaiAPI.getChatbot()`. `DiscussionsUI.js` + `DiscussionsSystem.js` ride on it. **Workspace's left
81 column = mount `DiscussionsSystem` with a `system` prop. Reuse, don't rebuild.**
82
83 **The one real extraction — the submit/stream state machine.** Inside `ChatbotContext` these members
84 are the reusable "chat session" logic, tangled together but separable from all the display params:
85 `onSubmit` (L867, the streaming submit), `addErrorMessage`/`retryLastQuery`/`lastFailedQuery`, `locked`,
86 `saveMessages` (localStorage), `refreshRestNonce`, the file-upload callbacks
87 (`onFileUpload`/`onUploadFile`/`onMultiFileUpload`), `messages`/`chatId`/`sessionId`/`previousResponseId`.
88 It needs only: botId, customId, sessionId, chatId, restNonce, and a **body-params bag** (envId, model,
89 temperature, mcpServers…) — NOT the ~70 display fields (aiName, avatars, theme, icon…) that make up the
90 rest of `state`. Backend already accepts those body params on `chats/submit` (MWAI_CHATBOT_SERVER_PARAMS),
91 so per-conversation model switching needs no server change.
92
93 **Thin display consumers (read state + call actions; ~11 files):** ChatbotUI, ChatbotBody, ChatbotReply,
94 ChatbotName, ChatbotHeader, ChatbotTrigger, ChatbotInput, ChatbotSubmit, ChatUploadIcon, ChatClearIcon,
95 MwaiFiles, plus TerminalMessages. These read a context shape; they don't care WHO provides it.
96
97 **Cross-surface consumers to not break:** `screens/chatbots/Chatbots.js` mounts `ChatbotSystem` (admin
98 preview); `premium/js/forms/FormSubmit.js` imports the `MwaiAPI` singleton. Both stay valid under the plan.
99
100 ### Extraction strategy (chosen: hook, not rewrite)
101
102 Per Jordy's "keep chatbots light, don't overcomplicate, no behavior change": extract the LOGIC into a
103 shared hook, keep the DISPLAY components as context-consumers, and give Workspace its own thin context of
104 the same shape. The chatbot keeps using `ChatbotContext` (now internally delegating), so its behavior is
105 byte-identical; Workspace supplies a compatible context that reuses the hook + the discussions sidebar.
106
107 - [x] **Extract `useChatSession()`** into `app/js/components/chat/` — the submit/stream/error/lock/upload/
108 localStorage machine listed above, parameterized by `{ botId, customId, session, restNonce, bodyParams }`.
109 `ChatbotContext` refactors to consume it and spread the result into its existing `state`/`actions` (no
110 API change to any consumer). This is the only behavior-sensitive change; it lands behind the smoke gate.
111 **Slice one DONE 2026-07-24: `useRestNonce`** (`app/js/components/chat/useRestNonce.js`): nonce state +
112 ref + tokenManager subscription + `updateToken` + `refreshRestNonce`(start_session), previously
113 duplicated VERBATIM in ChatbotContext and DiscussionsContext (3 more inline `handleTokenUpdate` copies
114 removed there). Both contexts consume it now. Verified: full smoke gate 35/0, live popup chat green,
115 chatbot.js size unchanged (303K). **Slice two DONE 2026-07-24: `useChatUploads`** (single + multi upload state, progress, the 6
116 callbacks against mwai-ui/v1/files/upload), moved verbatim; ChatbotContext passes addErrorMessage
117 as onError and its clear-errors behavior as onBeforeUpload. Gate 35/0, build clean, bundle 303K
118 unchanged, eslint errors down 54 → 52 (both remaining top offenders pre-exist, incl. the dormant
119 `setContentType` no-undef in updateComponentConfig, ChatbotContext ~L1284, worth a fix someday).
120 Uploads hand-tested by Jordy in the browser (2026-07-24): working.
121 **Slice three DONE 2026-07-24: the full `useChatSession`** (`app/js/components/chat/useChatSession.js`,
122 616 lines) composing useRestNonce + useChatUploads and owning messages/chatId/busy/locked/error state,
123 localStorage persistence, the streaming onSubmit, and the serverReply effect. Surface behaviors are
124 injected (makeInitialMessages, onQueryStart, onCleared, onActions/onShortcuts/onBlocks), so the
125 chatbot's eval-actions and shortcut/block handling stay chatbot-only while Workspace passes its own.
126 ChatbotContext went 1564 → 881 lines and exposes an IDENTICAL state/actions API. Verified: gate 35/0,
127 live browser chat (start sentence + streamed reply), bundle 303K unchanged. Phase 3 extraction COMPLETE.
128 - [~] **Verify no chatbot behavior change.** (Gate + live chat green after each slice; the broader
129 hands-on pass across popup/inline/discussions and 2-3 themes remains before calling the phase closed.)
130 Original item: Full smoke gate + hands-on popup/inline/discussions across
131 2-3 themes. `git diff` on `chatbot.js` bundle behavior must be nil. This is the gate for the whole phase.
132 - [ ] **Confirm reusables need no change:** ChatbotContent, ChatbotEvents, DiscussionsSystem/UI/Context,
133 helpers, tokenManager, MwaiAPI — used by Workspace as-is. (Inventory says yes; confirm at build time.)
134 - [ ] **Bundle discipline.** Workspace gets its own webpack entry (`workspace: './app/js/workspace.js'`,
135 own `chunkLoadingGlobal`) — the config already has 4 parallel entries, so this is ~5 lines. Verify
136 `chatbot.js` size does not grow from the `useChatSession` extraction.
137
138 ## Phase 4 — Workspace v1 (Pro only, admins only)
139
140 The pitch: "your own ChatGPT: every model, your API keys, no per-seat subscription." Full-screen,
141 history left, generous spacing. TypingMind/LibreChat/Mammouth class, inside WordPress.
142
143 **Design direction (Jordy, 2026-07-24):**
144 - **Structure like TypingMind** (left sidebar with chats, clean center pane, model picker up top),
145 but "extremely pretty": TypingMind's layout is the reference, NOT its level of refinement. We do
146 better. Bespoke design system for this surface (CSS variables, not NekoUI widgets: this is a
147 product surface, not an admin form).
148 - **Two themes only for v1: dark and light.** A theme toggle, both first-class. No full theming
149 engine for now.
150 - **Configurable accent color, Meow blue by default** (`--neko-blue`, hsl 217 80% 42%; brightened to
151 62% lightness on dark). A per-user preference like the theme; the mock ships 5 swatches (blue,
152 brass, teal, rose, violet). Approved by Jordy on the mock, 2026-07-24.
153 - **Mock approved 2026-07-24** (`labs/workspace-mock.html`, view at
154 ai.nekod.net/wp-content/plugins/ai-engine-pro/labs/workspace-mock.html). It is the design
155 reference for the real build.
156 - **Settings are PER WORDPRESS USER** (user meta, e.g. `mwai_workspace_prefs`: theme, default
157 env/model, sidebar state…). AI Engine Settings barely configures Workspace itself; later it becomes
158 the place where admins LIMIT what users can set (allowed envs/models, spend caps per user). For v1:
159 admins only, so limits can wait.
160
161 - [x] **Skeleton.** SHIPPED 2026-07-24: `module_workspace` toggle (Modules > Chatbots & Knowledge,
162 Pro), full-screen admin page `admin.php?page=mwai_workspace` under Meow Apps (chrome hidden),
163 own webpack entry (`app/workspace.js`, 104K, chunk global wpJsonMwaiWorkspace), dark/light +
164 accent via per-user prefs (user meta `mwai_workspace_prefs`, REST `mwai/v1/workspace/prefs`),
165 `premium/workspace.css` from the approved mock. Runs on the internal bot `mwai_workspace`
166 (mwai_internal_chatbot filter, based on the default bot, admin-gated).
167 - [x] **Chat pane** SHIPPED 2026-07-24 on `useChatSession` (streaming, markdown via the shared
168 ChatbotContent incl. code copy, error rendering, thinking dots, autoscroll).
169 - [x] **History sidebar** SHIPPED 2026-07-24 on the discussions REST (list by botId, date groups,
170 client search, AI titles, inline rename, two-step delete, new chat, auto-refresh after replies).
171 - [x] **Model picker** SHIPPED 2026-07-24: envs + chat models grouped with provider dots
172 (catalog built server-side with the smoke-gate filtering); selection is sent per-request as
173 envId/model body params and remembered in prefs. Advanced params (temperature…) still open.
174 - [x] **Icon rail + collapsible panel** SHIPPED 2026-07-24 (Jordy's TypingMind-column ask): far-left
175 rail always visible (Nyao logo, accent + New chat, Chats/Prompts/Agents-soon, Settings + Admin at
176 bottom, 10px labels); the old sidebar is now a sliding panel (collapse chevron in header; clicking
177 the active rail item toggles; collapsed state persists in prefs). Theme + accent moved from the
178 user card into the Settings panel (segmented Dark/Light + swatch row). Agents = coming-soon panel
179 (chat-nyao-2 robot cat). Access points shipped same day: Admin Bar entry (on by default, toggle in
180 Settings > Others > Admin Bar), NekoHeader button, Meow Apps menu entry removed (hidden page +
181 admin_title filter).
182 - [x] **Prompt library v1** SHIPPED 2026-07-24: per-user saved prompts (title + text, in
183 `mwai_workspace_prefs`, sanitized server-side, capped 200×20k chars); one click inserts into the
184 composer (appends if text present) and focuses it; inline editor, two-step delete.
185 - [x] **Composer toolbar (TypingMind-style features + pins)** SHIPPED 2026-07-24: [+] menu listing
186 Attach files / Knowledge / MCP Servers / Functions with per-feature pin toggles (pins persist in
187 prefs; default pinned: uploads + knowledge); an ACTIVE feature's icon always shows even unpinned,
188 with a count badge. Popovers anchored above the composer, click-outside + focus-composer close.
189 - [x] **Uploads** SHIPPED 2026-07-24: multi-upload (8 max) via paperclip, drag/drop over the whole
190 pane (dashed overlay), paste; chips with image thumbnails/doc icons, per-file progress, remove;
191 image previews inside the sent bubble; over-limit and invalid-file handled with friendly notices;
192 soft amber warning when the model lacks the vision tag (never blocks). Verified: 6 files at once
193 (3 PNG read correctly by GPT-5.6 Sol), txt content extracted server-side and answered from.
194 - [x] **Knowledge** SHIPPED 2026-07-24: brain popover picks an embeddings env per conversation
195 (None + list, persists as default in prefs), sent as embeddingsEnvId body param (same channel as
196 chatbots). Verified both ways with the Internal DB: connected → answers the secret passphrase;
197 None → does not know it.
198 - [x] **MCP Servers + Functions** SHIPPED 2026-07-24: plug/braces popovers (multi-select from
199 mcp_envs and mwai_functions_list minus editor-assistant), sent per-request as mcpServers/functions
200 (function-aware chatbot_query consumes them). Verified: Offbeat Japan MCP listed real latest
201 posts via GPT-5.6 Sol; Code Engine functions returned the magic word + relayed a failing sensor
202 gracefully; Gemini mid-thread switch degraded gracefully (functions yes, external MCP no: the
203 known Gemini gap). Empty/module-off states link to settings.
204 - [x] **Create Image** BUILT 2026-07-24 (uncommitted, per Jordy's ask; commit with his review): a toggle
205 in the composer [+] menu (pinnable, photo icon, status "On"). When on, the request carries
206 tools:['image_generation']: the OpenAI engine maps it to the native Responses image tool, Gemini
207 Flash Image models output images natively (toggle harmless there), other models get a soft amber
208 warning naming capable models. Model catalog gained an `image` capability flag (OpenAI model
209 tools + Google image-generation feature). Images come back as markdown (Reply::set_choices saves
210 b64 per the image settings), so rendering AND discussion persistence are free; Workspace CSS
211 upsizes .mwai-image to 480px with radius+shadow (the shared renderer inline-caps at 220px, hence
212 !important). Live QA all green: GPT-5.6 Sol generation; GPT multi-turn edit (snow + lantern added
213 to the same scene); upload-an-image + edit (bicycle→red scooter, scene preserved); Gemini 3.1
214 Flash Image generation + in-context edit (watercolor of the same kitchen); Claude soft warning;
215 trail shows "Generating image..."; images + per-message model chips survive reload.
216 - [x] **Stop button** SHIPPED 2026-07-24: AbortController in useChatSession (stopGeneration);
217 partial reply kept with a STOPPED chip; the turn persists through discussions/truncate, which now
218 also creates the row for first-turn stops and keeps stopped/extra.model through sanitization.
219 - [x] **Per-message model attribution** FIXED 2026-07-24: assistant messages store extra.model
220 server-side (discussions), live messages stamped at submit time; chips now show the model that
221 actually answered (verified o3 vs GPT-5.6 Sol vs Gemini 3.1 Pro in one thread).
222 - [x] **Real errors for admins** 2026-07-24: streaming errors pass the actual provider message to
223 manage_options users (visitors keep the generic one). Found + fixed en route: error messages were
224 invisible in the Workspace (its own admin-notice-hiding CSS matched the .error class; renamed to
225 .is-error), and the OpenAI Responses API sent temperature to o-series models (400) — now gated
226 like chatml via o1-model/no-temperature tags.
227 - [x] **QoL batch 2026-07-25:** generated-image lifetime now honors the Files > Expiration setting
228 everywhere (the "Never" default silently fell through to the 1h uploaded-files TTL; fixed in
229 Reply::save_temp_image_from_b64 for chatbots AND Workspace, replacing an earlier
230 workspace-only 10y override); pinned conversations (prefs.pinnedChats, PINNED sidebar group, pin icon in row
231 actions); export-as-Markdown icon in row actions; ChatGPT-style time chips between messages
232 ("Today 6:36 PM", stored timestamps now saved on discussion messages + kept by truncate);
233 a "..." menu on AI messages with the message time and **Branch in new chat** (copies the thread
234 up to that message into a new server-backed discussion via the truncate endpoint); keyboard
235 shortcuts (Cmd/Ctrl+K new chat in capture phase so WP's own palette stays closed, Esc stops
236 generation); hint line documents them. All verified live; smoke gate 35/0.
237 - [x] **This WordPress (MCP tools as functions)** SHIPPED 2026-07-25 (Jordy's ask; bridge over
238 self-MCP for reachability + all-provider coverage): globe entry in the [+] menu with a master
239 toggle ("Work on {site}") and per-category checkboxes (Core preselected; counts + tool-name
240 tooltips), pinnable, persisted (prefs wpMode/wpCategories). Client sends `wpTools:[categories]`;
241 workspace.php stashes it in mwai_internal_chatbot (admin + workspace-bot only), converts the
242 matching `mwai_mcp_tools` schemas into functions on mwai_chatbot_query (new
243 `Meow_MWAI_Query_Function::from_raw_schema` + rawSchema passthrough in all four serializers),
244 and executes via the `mwai_mcp_callback` filter in an mwai_ai_feedback handler (JSON-RPC/MCP
245 envelopes unwrapped, Throwable-contained, int call id since handlers type `?int $id`). Tool
246 catalog is served by REST (`workspace/wp-tools`) because core registers its tools filter on
247 rest_api_init only. maxDepth raised to 20 for workspace scope (find→read→edit→verify burns 5+).
248 Verified live: GPT-5.6 Luna counts+lists posts; Claude Opus 5 full write flow (find draft,
249 append haiku, read back, ID+permalink); Gemini 3.5 Flash Interactions protocol correct
250 (function_result+call_id+previous_interaction_id; the model itself over-calls tools — its
251 quirk, stray write failed safely on validation).
252 - [x] **Anthropic multi-round function calling FIXED plugin-wide 2026-07-25** (found via the
253 bridge, affects chatbots too, likely the real cause of Jordy's "Claude re-calls tools" report):
254 engines/core.php cleared the feedback blocks on every recursion, so stateless providers
255 (Anthropic, Chat Completions, classic Gemini) lost every earlier tool exchange of the turn —
256 round 3 sent only round 2's pair, the model re-issued identical calls and tripped the loop
257 detector. Blocks now ACCUMULATE for stateless replies (engines replay assistant tool_use +
258 tool_result per block, rebuilding the chain) and still reset for stateful ones (OpenAI
259 Responses, Google Interactions, Assistants) which hold history server-side.
260 - [x] **Claude Opus 5 added 2026-07-25** (claude-opus-5, family claude-5, no-temperature,
261 1M ctx / 128k out, $5/$25; 'latest' moved off Opus 4.8). Verified live in the Workspace.
262 - [x] **Image lifetime in the lightbox** SHIPPED 2026-07-25 (Jordy's ask): the lightbox bar shows a
263 live 1s-ticking countdown chip driven by the temp-file record ("Expires in 57m 41s", amber under
264 10 min, "Kept forever" when the setting is Never, green "In Media Library" for attachments) via
265 REST `workspace/image-info` (URL → expires, server-clock offset applied client-side), plus a
266 **Save to Media Library** action via `workspace/image-persist`: copies the file into a real
267 attachment (wp_upload_bits + wp_insert_attachment + metadata), rewrites the URL in the stored
268 discussion messages AND the live thread, then deletes the temp file record. Verified live:
269 generated with a 1h TTL → countdown ticks → saved → chip flips to In Media Library → reload
270 serves the attachment URL from the rewritten history.
271 - [x] **Batch 2026-07-25 (post-review):** WordPress Tools rename + official WP mark icon (the
272 globe didn't read as WordPress; filled path overrides the stroke-based icon set); advanced
273 model params in the topbar (temperature slider, hidden-locked on no-temperature models;
274 reasoning-effort segmented control on reasoning models; per-user prefs.advanced; build_envs now
275 exposes the reasoning/no-temperature tags); server-side conversation search (the shared
276 discussions chats_query 'preview' filter now matches title too, and the UI list endpoint takes
277 a `search` param — usable by the chatbot discussions UI as well; Workspace sidebar debounces
278 into it past the loaded 50); Settings > Workspace section (workspace_image/_wp_tools/_mcp/
279 _functions/_knowledge availability toggles, defaults on, enforced server-side in chatbot_query +
280 wpTools stash + hidden in the composer). Verified live incl. toggling Create Image off.
281 Full gaps list mirrored in ~/Desktop/WORKSPACE-MISSING.md (permission dialogs = top item).
282 - [x] **Freemium split** SHIPPED 2026-07-25 (Jordy's call, matching the strategy discussion):
283 the Workspace moved to the free core (classes/modules/workspace.php, app/workspace.css,
284 Meow_MWAI_Modules_Workspace, instantiated from classes/core.php on module_workspace, no more
285 requirePro on the module toggle). Knowledge, MCP Servers and Functions stay Pro: their Settings
286 checkboxes are requirePro, the server computes effective flags (option AND is_registered) and
287 strips them from the query, and unregistered installs see them as tasteful locked "Pro" rows in
288 the [+] menu linking to meowapps.com. WordPress Tools (core, free MCP) and Create Image stay
289 free. Settings > Workspace gained a Roles block stating admins-only for now.
290 - [x] **Tool approval dialogs** SHIPPED 2026-07-25 (the top item of the gaps list): any
291 WordPress Tool that can change the site (MCP readOnlyHint annotations; name-heuristic fallback,
292 unknown verbs count as writes) pauses the turn via Meow_MWAI_ApprovalRequiredException. The
293 pipeline turns it into an in-thread approval card (custom UI: tool name, args JSON, Deny /
294 Allow Once / Always Allow in This Chat), stores nothing while pending, and the decision resumes
295 the turn through the edit-message truncate+resubmit primitive with the decision riding along
296 (wpToolsAllowed/wpToolsDenied params). A per-turn transient cache returns already-executed
297 write results on re-runs so approving call 2 never re-executes call 1 (no duplicate posts).
298 Verified live: create paused, Allow Once created exactly one post; Deny handed the refusal to
299 the AI ("no changes were made"); Always Allow let a two-post turn complete with one card.
300 Stale-closure gotcha: the resume MUST go through a latest-ref or it submits pre-decision atts.
301 - [x] **Conversation folders** SHIPPED 2026-07-25: per-user named folders in the sidebar
302 (prefs.folders, max 30, sanitized server-side), one folder per conversation, assigned via a
303 folder menu on each row (with inline "New folder..."), collapsible groups with count chips,
304 hover rename + two-step delete (deleting releases the chats back to the date groups), folder
305 membership wins over date groups and Pinned, folders with no matches hide during search.
306 Verified live incl. collapse-state persistence across reloads.
307 - [ ] **Pinned conversations vs retention:** the discussions cleanup deletes old rows regardless
308 of Workspace pins (a pinned chat vanished after retention ran). Either exclude pinned chatIds
309 from cleanup or prune dead pins from prefs. Small, worth doing with folders.
310 - [ ] **Roles beyond admin** parked (Jordy 2026-07-25): needs a real permissions design first,
311 because by default a user could pick any environment, model, and feature. The settings surface
312 for restricting envs/models/features per role is the prerequisite, not the role toggle itself.
313 - [~] **v1 polish:** per-conversation cost badge wired. Still open: folders (pins shipped),
314 self-hosted fonts (Google Fonts CDN for now, admin page only), image previews for reloaded
315 conversations (server stores text only).
316 **QA 2026-07-24 (all green):** two full passes incl. adversarial (corrupt PNG rejected with a
317 friendly error, 8-file limit notice, stop before first token, [ERROR] hook, light+dark for all
318 new UI, pin/unpin round-trips); smoke gate 35/0 after each batch.
319 - [ ] **Later (v2+):** roles beyond admin, front-end variant, agents, shared/team conversations.
320
321 ## Standing rules for this program
322
323 - One commit per finished, tested item; smoke gate (`node labs/tests/test-smoke.js`) before each
324 chatbot/engine-path commit.
325 - Bundles stay out of fix commits (Nekofy sweeps them at release).
326 - Anything that grows `chatbot.js` for Workspace's benefit is wrong; separate entry.
327 - Tick items here as they land; /pulse may surface the top unchecked item.
328