# MEMANTO Integration Plan — Optional Context Enhancement **Version:** 1.0 **Date:** 2026-06-07 **Status:** Planning **Depends on:** MEMANTO_PRICING_STRATEGY.md --- ## Design Principles 1. **MEMANTO is optional.** The plugin's built-in Context Builder (`class-context-builder.php`) remains the default and always works without MEMANTO. 2. **MEMANTO enhances, never replaces.** MySQL sessions (`wpaw_conversations`) remain the primary session store. MEMANTO runs parallel. 3. **Zero disruption on failure.** If MEMANTO is unreachable, the plugin falls back to existing behavior with no error shown to the user. 4. **Server-side only.** All MEMANTO API calls happen in PHP. The frontend (sidebar.js) is unaware of MEMANTO — it just sees richer or leaner context in AI responses. 5. **User brings own Moorcheh key.** Plugin stores MEMANTO URL + Moorcheh API key in WordPress settings. Never hardcoded. --- ## Architecture Overview ``` ┌────────────────────────────────────────────────┐ │ WordPress Backend │ │ │ User Message ──────► │ Gutenberg Sidebar (handle_chat_request) │ │ │ │ │ ▼ │ │ Context Builder (build_system_message) │ │ │ │ │ ├──► MySQL Session (wpaw_conversations) │ │ │ primary store │ │ │ │ │ ├──► Memanto Client ──► MEMANTO API │ │ │ (if configured) │ │ │ │ │ │ │ ├── recall (retrieve) │ │ │ └── remember (store) │ │ │ │ │ ▼ │ │ Merged Context → AI Provider → Response │ └────────────────────────────────────────────────┘ ``` ### Data Flow: Two Paths | Path | When | What Happens | |---|---|---| | **Default (no MEMANTO)** | MEMANTO URL not configured in settings | Context Builder uses MySQL session only. Identical to current behavior. | | **MEMANTO active** | MEMANTO URL + Moorcheh key configured and validated | Context Builder queries MEMANTO for relevant memories before building context. After AI response, significant events are stored in MEMANTO. | --- ## Agent Design ### Agent Naming Convention | Agent ID | Scope | Purpose | |---|---|---| | `wp-user-{wordpress_user_id}` | Per WordPress user | Cross-post preferences: writing style, tone, audience, language, brand voice | | `wp-post-{wordpress_post_id}` | Per post | Article-specific: plan decisions, rejections, research, section progress | ### Memory Types Used | MEMANTO Type | When Stored | Example | |---|---|---| | `preference` | User sets/changes post config | "User prefers conversational tone, intermediate audience" | | `instruction` | User sends chat message | "Focus on plugin vulnerabilities only" | | `decision` | User approves/rejects plan | "Approved 5-section outline for WordPress security" | | `artifact` | Plan generated, section written | "Plan: 5 sections covering X, Y, Z" | | `context` | Session ends / summarize | "Article at 60% completion, 3 of 5 sections done" | | `error` | User corrects AI output | "User rejected generic tips approach, wants specific plugin recommendations" | ### Tags Convention Tags enable targeted recall. Every memory includes: | Tag | Example | Purpose | |---|---|---| | `post:{id}` | `post:42` | Scope recall to specific post | | `site:{domain}` | `site:example.com` | Scope to WordPress site | | `mode:{mode}` | `mode:planning` | What mode was active | | `model:{model}` | `model:deepseek-chat` | Which model was used | --- ## New Files to Create ### `includes/class-memanto-client.php` PHP client for MEMANTO API v2. Singleton class. **Public Methods:** | Method | Description | |---|---| | `is_configured()` | Returns true if MEMANTO URL + Moorcheh key are set in settings | | `is_healthy()` | Calls `/health` endpoint, caches result for 5 minutes | | `ensure_agent( $agent_id )` | Creates agent via `POST /api/v2/agents` if not exists | | `activate_session( $agent_id )` | `POST /api/v2/agents/{id}/activate`, caches session token in transient | | `remember( $agent_id, $content, $type, $tags, $title )` | `POST /api/v2/agents/{id}/remember` | | `batch_remember( $agent_id, $memories )` | `POST /api/v2/agents/{id}/batch-remember` | | `recall( $agent_id, $query, $type, $limit )` | `POST /api/v2/agents/{id}/recall` | | `recall_recent( $agent_id, $limit )` | `POST /api/v2/agents/{id}/recall/recent` | | `deactivate_session( $agent_id )` | `POST /api/v2/agents/{id}/deactivate` | **Internal Mechanics:** - Session token stored in WP transient: `wpaw_memanto_token_{agent_id}` (6-hour TTL matching MEMANTO JWT) - Auto-reactivates on expired token (catches 401, re-activates, retries) - All calls use `wp_remote_post` / `wp_remote_get` with 10-second timeout - All calls wrapped in try/catch with `wpaw_debug_log` on failure - Moorcheh API key passed via `X-API-Key` header or configured in MEMANTO instance (depending on MEMANTO's auth model) ### `includes/class-memanto-context-enhancer.php` Orchestrates when and what to remember/recall. Hooks into existing Context Service. **Public Methods:** | Method | Hook Point | Description | |---|---|---| | `on_session_start( $session_id, $post_id, $user_id )` | Session creation | Ensures user + post agents exist; recalls previous session state | | `on_user_message( $session_id, $content, $post_id )` | After user sends message | Stores instruction-type memory | | `on_plan_generated( $post_id, $plan )` | After plan creation | Stores artifact-type memory | | `on_plan_approved( $post_id, $plan )` | User approves plan | Stores decision-type memory | | `on_plan_rejected( $post_id, $reason )` | User rejects/requests changes | Stores error-type memory with rejection reason | | `on_section_written( $post_id, $section_id, $summary )` | After section generation | Stores artifact-type memory | | `on_block_refined( $post_id, $block_id, $instruction )` | After refinement | Stores instruction-type memory | | `on_config_saved( $post_id, $config )` | Post config updated | Stores preference-type memory to both user and post agents | | `on_session_end( $session_id, $post_id )` | Session completed/archived | Summarizes session, stores context-type memory, deactivates session | | `recall_for_context( $post_id, $user_id, $current_message )` | Before building context | Returns recalled memories to enrich prompt | **Recall Strategy (`recall_for_context`):** 1. Recall recent memories from post agent (limit: 10) 2. Recall semantically relevant memories from post agent (query: user's current message, limit: 5) 3. Recall user preferences from user agent (query: "writing preferences tone audience", limit: 5) 4. Deduplicate by content hash 5. Return structured array of recalled items --- ## Files to Modify ### `includes/class-settings-v2.php` Add MEMANTO configuration section: ``` MEMANTO Context Keeper ├── Enable MEMANTO integration (checkbox, default: off) ├── MEMANTO Instance URL (text, e.g., https://abc123.context.wpagentic.dev) ├── Moorcheh API Key (password, user's own key) └── Connection Status (read-only, shows "Connected" / "Not configured" / "Error: ...") ``` Add a "Test Connection" button that calls MEMANTO `/health` endpoint. ### `includes/class-context-builder.php` Modify `build_for_task()` method. After line ~52 where `$saved_context` is loaded: ```php // Existing: MySQL context $saved_context = $context_service->get_context( $session_id, $post_id ); // NEW: MEMANTO enhancement (if configured) $memanto_context = array(); $memanto_client = WP_Agentic_Writer_Memanto_Client::get_instance(); if ( $memanto_client->is_configured() && $memanto_client->is_healthy() ) { $enhancer = WP_Agentic_Writer_Memanto_Context_Enhancer::get_instance(); $memanto_context = $enhancer->recall_for_context( $post_id, get_current_user_id(), $request_params['latestUserMessage'] ?? '' ); } ``` Modify `build_working_context()` to include a new section: ```php // After existing sections, before "Recent saved conversation excerpts" if ( ! empty( $memanto_context ) ) { $memory_lines = $this->format_memanto_memories( $memanto_context ); if ( '' !== $memory_lines ) { $sections[] = "PERSISTENT MEMORY (recalled from MEMANTO):\n" . $memory_lines; } } ``` **Key rule:** MEMANTO context is **additive**. It never replaces the existing `BACKEND CONTINUITY CONTEXT` section. It supplements it. ### `includes/class-context-service.php` Add MEMANTO write-through hooks in key methods: | Method | Hook Added | |---|---| | `save_plan()` | `$enhancer->on_plan_generated( $post_id, $plan )` | | `update_session_context()` | `$enhancer->on_config_saved()` if config changed | | `add_message()` | `$enhancer->on_user_message()` for user-role messages | | `clear_context()` | Optionally clear MEMANTO post agent memories | ### `includes/class-gutenberg-sidebar.php` Add MEMANTO hooks in key handler methods: | Handler | Hook Added | |---|---| | `handle_chat_request()` | `$enhancer->on_user_message()` after saving to MySQL | | `handle_generate_plan()` | `$enhancer->on_plan_generated()` after successful plan | | `handle_execute_article()` | `$enhancer->on_section_written()` per section | | `handle_refine_block()` | `$enhancer->on_block_refined()` | | `handle_summarize_context()` | Skip AI call if MEMANTO active — return cached recall instead | | `handle_detect_intent()` | Skip AI call if MEMANTO active — use regex + MEMANTO context instead | Add new REST endpoint: ``` POST /wp-agentic-writer/v1/memanto/status → Returns: { connected: bool, agent_count: int, memory_count: int, last_recall: string } ``` ### `includes/class-autoloader.php` Register the two new classes: - `class-memanto-client.php` → `WP_Agentic_Writer_Memanto_Client` - `class-memanto-context-enhancer.php` → `WP_Agentic_Writer_Memanto_Context_Enhancer` ### `assets/js/sidebar.js` (minimal change) No MEMANTO-specific logic needed. Optional enhancement: - Show a small "🧠 Memory active" indicator when MEMANTO is connected - Show "memories recalled: N" in the context audit display --- ## Graceful Degradation Strategy ``` MEMANTO call succeeds? ├── YES → Merge MEMANTO context into working context └── NO ├── MEMANTO not configured → Use MySQL-only context (default behavior) ├── MEMANTO timeout (>10s) → Log warning, use MySQL-only context ├── MEMANTO 401 (token expired) → Re-activate session, retry once, then fallback └── MEMANTO 5xx (server error) → Log error, use MySQL-only context ``` User **never** sees an error from MEMANTO. The worst case is they get the same experience as users without MEMANTO. --- ## Implementation Phases ### Phase 1: Core Client (Week 1) **Goal:** MEMANTO client class + settings UI + connection validation | Task | File | Details | |---|---|---| | Create Memanto Client | `class-memanto-client.php` | All API methods, session token management, error handling | | Create Context Enhancer shell | `class-memanto-context-enhancer.php` | Skeleton with `is_configured()` check on every method | | Add settings section | `class-settings-v2.php` | URL field, API key field, enable checkbox, test button | | Register in autoloader | `class-autoloader.php` | Add both new classes | | Add REST status endpoint | `class-gutenberg-sidebar.php` | `/memanto/status` endpoint | **Validation:** Admin can configure MEMANTO URL + Moorcheh key, test connection, see "Connected" status. No functional changes to AI features yet. ### Phase 2: Write-Through Memory (Week 2) **Goal:** Store memories on every meaningful action | Task | Hook Point | Memory Type | |---|---|---| | Store on user message | `handle_chat_request()` | `instruction` | | Store on plan generated | `handle_generate_plan()` | `artifact` | | Store on plan approved | After plan save in frontend | `decision` | | Store on plan rejected | Plan revision flow | `error` | | Store on section written | `handle_execute_article()` | `artifact` | | Store on block refined | `handle_refine_block()` | `instruction` | | Store on config saved | `update_session_context()` | `preference` | | Store on session end | Session completed/archived | `context` | **Validation:** Write an article with MEMANTO enabled. Check MEMANTO API (via recall endpoint) that memories were stored. Verify plugin still works perfectly with MEMANTO disabled. ### Phase 3: Context Enrichment (Week 3) **Goal:** Recall memories to enrich AI prompts | Task | File | Details | |---|---|---| | Add `recall_for_context()` | `class-memanto-context-enhancer.php` | 3-recall strategy (recent, semantic, preferences) | | Modify `build_for_task()` | `class-context-builder.php` | Merge recalled memories into working context | | Add `format_memanto_memories()` | `class-context-builder.php` | Format recalled items as compact prompt text | | Skip summarize-context when MEMANTO active | `class-gutenberg-sidebar.php` | Return cached recall instead of AI call | | Skip detect-intent when MEMANTO active | `class-gutenberg-sidebar.php` | Use regex + MEMANTO context instead | **Validation:** Write an article. Mid-session, close the browser. Reopen the post. Verify AI "remembers" context from recalled memories. Compare AI response quality with/without MEMANTO. ### Phase 4: Cross-Session Restore (Week 4) **Goal:** Seamless experience when returning to a post after days/weeks | Task | Details | |---|---| | Session restore on load | When post editor opens, recall recent post memories. Build a "restored session" system message. | | Frontend indicator | Show "🧠 Restored from memory" badge in sidebar | | User preference carry-over | On new post creation, recall user agent preferences for default post config | | Session deactivation | On session end, call MEMANTO deactivate to trigger summary generation | **Validation:** Create an article. Complete 50%. Wait 1 day. Open the post again. Verify AI picks up where it left off without user re-explaining context. ### Phase 5: Polish & Edge Cases (Week 5) | Task | Details | |---|---| | Memory pruning | On session end, summarize verbose raw messages into compact context memories | | Connection health UI | Real-time status indicator in plugin sidebar header | | Moorcheh limit warning | When approaching 10K vectors, show admin notice with upgrade link | | Error logging | Detailed MEMANTO error logging with `wpaw_debug_log` | | Settings validation | Validate URL format, API key format, connection test before saving | --- ## Testing Strategy ### Unit Tests | Test | Description | |---|---| | `test_memanto_client_not_configured` | Client returns false when settings empty | | `test_memanto_client_health_check` | Mock `/health` response, verify caching | | `test_memanto_client_remember` | Mock remember API, verify payload structure | | `test_memanto_client_recall` | Mock recall API, verify response parsing | | `test_memanto_client_session_lifecycle` | Activate → remember → recall → deactivate | | `test_enhancer_graceful_fallback` | MEMANTO returns error, context builder still works | | `test_context_builder_with_memanto` | Verify MEMANTO context is included in working context | | `test_context_builder_without_memanto` | Verify no MEMANTO content when not configured | ### Integration Tests | Test | Description | |---|---| | Full article with MEMANTO | Chat → Plan → Write → Refine. Verify memories stored at each step. | | Full article without MEMANTO | Same flow. Verify no MEMANTO calls made. Plugin works identically. | | MEMANTO goes down mid-session | Start with MEMANTO active. Simulate timeout. Verify graceful fallback. | | Cross-session restore | Write 50% of article. Simulate new session. Verify AI context restored. | | Multi-site with same MEMANTO | Use same MEMANTO instance across 2 sites. Verify agent isolation. | ### Manual Test Checklist - [ ] Plugin activates with no MEMANTO settings — works normally - [ ] MEMANTO URL set but Moorcheh key empty — shows "not configured" - [ ] MEMANTO URL + invalid key — shows "connection error" - [ ] MEMANTO URL + valid key — shows "connected" - [ ] Write article with MEMANTO on — AI responses include recalled memory - [ ] Write article with MEMANTO off — identical to current behavior - [ ] Disable MEMANTO mid-session — no errors, fallback to MySQL-only - [ ] Re-enable MEMANTO — picks up from where it left off - [ ] Check MEMANTO recall endpoint — memories exist for test post --- ## Performance Considerations | Concern | Mitigation | |---|---| | MEMANTO recall adds latency to every AI call | Cache recall results in transient (5-min TTL). Only recall when context builder runs. | | Session token expires mid-request | Auto-reactivate on 401. Single retry. | | Too many memories stored | Batch-remember to reduce HTTP calls. Summarize on session end. | | MEMANTO instance overloaded | 10-second timeout on all calls. Graceful fallback. | | WordPress transient cache bloat | Use specific key patterns. Clean up on session end. | --- ## Settings UI Specification ### MEMANTO Context Keeper Section Located in WP Agentic Writer → Settings → MEMANTO tab. ``` ┌─────────────────────────────────────────────────────────────────┐ │ MEMANTO Context Keeper │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ☑ Enable MEMANTO integration │ │ │ │ MEMANTO Instance URL │ │ ┌──────────────────────────────────────────────────┐ │ │ │ https://abc123.context.wpagentic.dev │ │ │ └──────────────────────────────────────────────────┘ │ │ │ │ Moorcheh API Key │ │ ┌──────────────────────────────────────────────────┐ │ │ │ •••••••••••••••••••••••• │ │ │ └──────────────────────────────────────────────────┘ │ │ ℹ️ Get a free API key at moorcheh.ai (10K vectors/month) │ │ │ │ Connection Status: 🟢 Connected │ │ Last checked: 2 minutes ago │ │ │ │ [Test Connection] │ │ │ ├─────────────────────────────────────────────────────────────────┤ │ ℹ️ MEMANTO is an optional add-on that provides persistent │ │ memory for your AI writing assistant. Your AI will remember │ │ context across sessions and posts. The plugin works │ │ perfectly without MEMANTO. │ │ │ │ Get MEMANTO at: wpagentic.dev/memanto │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## Summary | Aspect | Decision | |---|---| | **Scope** | Optional enhancement, not a dependency | | **New files** | `class-memanto-client.php`, `class-memanto-context-enhancer.php` | | **Modified files** | `class-context-builder.php`, `class-context-service.php`, `class-gutenberg-sidebar.php`, `class-settings-v2.php`, `class-autoloader.php` | | **Frontend changes** | Minimal: status indicator only | | **Fallback behavior** | Full graceful degradation to MySQL-only context | | **Implementation time** | 5 weeks (1 week per phase) | | **Testing priority** | Phase 2 (write-through) and Phase 3 (recall) are critical paths | --- **Document Date:** June 7, 2026 **Status:** Draft — Ready for Phase 1 implementation