diff --git a/integrations/openclaw/README.md b/integrations/openclaw/README.md index 4db861feb2..48b67afe35 100644 --- a/integrations/openclaw/README.md +++ b/integrations/openclaw/README.md @@ -71,7 +71,6 @@ Humans should follow the Quick Start below. "enabled": true, "tokenBudget": 1500, "rerank": true, - "keywordSearch": true, "identityAlwaysInclude": true }, "dream": { "enabled": true }, @@ -313,8 +312,8 @@ Enabled by default during `openclaw mem0 init`. `autoRecall` and `autoCapture` a | `skills.triage.enabled` | `boolean` | `true` | Enable fact extraction from conversations | | `skills.recall.enabled` | `boolean` | `true` | Enable memory recall before each turn | | `skills.recall.tokenBudget` | `number` | `1500` | Max tokens for injected memories | -| `skills.recall.rerank` | `boolean` | `true` | Rerank search results for relevance | -| `skills.recall.keywordSearch` | `boolean` | `true` | Augment with keyword-based search | +| `skills.recall.rerank` | `boolean` | `false` | Platform mode only: apply Mem0 Advanced Retrieval reranking on top of local ranking. No effect in open-source mode. | +| `skills.recall.keywordSearch` | `boolean` | `false` | Deprecated no-op. Mem0 v3 removed keyword search from the search API; this key is retained for backwards compatibility and has no effect. | | `skills.recall.identityAlwaysInclude` | `boolean` | `true` | Always include identity memories | | `skills.dream.enabled` | `boolean` | `true` | Enable periodic memory consolidation | | `skills.domain` | `string` | `"companion"` | Domain overlay for triage rules | diff --git a/integrations/openclaw/index.ts b/integrations/openclaw/index.ts index 3aa2a3314a..78a1c9b4a5 100644 --- a/integrations/openclaw/index.ts +++ b/integrations/openclaw/index.ts @@ -299,7 +299,9 @@ const memoryPlugin = definePluginEntry({ } // Helper: build search options (skills config overrides legacy defaults) - // v3.0.0: removed keyword_search, reranking, filter_memories, limit + // v3.0.0 removed keyword_search and filter_memories from the search API + // (keywordSearch stays a documented no-op). rerank is still supported and + // is threaded through when the user opts in (platform-only; OSS ignores). function buildSearchOptions( userIdOverride?: string, limit?: number, @@ -314,6 +316,7 @@ const memoryPlugin = definePluginEntry({ source: "OPENCLAW", }; if (runId) opts.run_id = runId; + if (recallCfg?.rerank) opts.rerank = true; return opts; } diff --git a/integrations/openclaw/openclaw.plugin.json b/integrations/openclaw/openclaw.plugin.json index 2b867f0048..d71352e0bb 100644 --- a/integrations/openclaw/openclaw.plugin.json +++ b/integrations/openclaw/openclaw.plugin.json @@ -271,8 +271,8 @@ "strategy": { "type": "string", "enum": ["always", "smart", "manual"] }, "tokenBudget": { "type": "number" }, "maxMemories": { "type": "number" }, - "rerank": { "type": "boolean" }, - "keywordSearch": { "type": "boolean" }, + "rerank": { "type": "boolean", "description": "Platform mode only: apply Mem0 Advanced Retrieval reranking to search results. No effect in open-source mode." }, + "keywordSearch": { "type": "boolean", "description": "Deprecated no-op. Mem0 v3 removed keyword search from the search API; retained for backwards compatibility and has no effect." }, "filterMemories": { "type": "boolean" }, "threshold": { "type": "number" }, "identityAlwaysInclude": { "type": "boolean" }, diff --git a/integrations/openclaw/providers.ts b/integrations/openclaw/providers.ts index b345aa5024..7ca3b94c1e 100644 --- a/integrations/openclaw/providers.ts +++ b/integrations/openclaw/providers.ts @@ -146,6 +146,9 @@ class PlatformProvider implements Mem0Provider { if (options.top_k != null) opts.topK = options.top_k; if (options.threshold != null) opts.threshold = options.threshold; if (options.categories != null) opts.categories = options.categories; + // Platform-only Advanced Retrieval reranking. The SDK's SearchMemoryOptions + // accepts `rerank` and camelToSnakeKeys forwards it to the v3 search API. + if (options.rerank) opts.rerank = true; // Build filters with user_id/run_id inside (v3.0.0 requirement) // Filters use snake_case as they're passed directly to the API @@ -574,13 +577,15 @@ export function providerToBackend( }, async search(query, opts = {}) { - // v3.0.0: removed keyword_search, reranking + // v3.0.0 removed keyword_search; rerank is still supported and forwarded + // when requested (platform-only — OSS provider ignores it). const results = await provider.search(query, { user_id: opts.userId ?? userId, top_k: opts.topK, threshold: opts.threshold, filters: opts.filters, source: "OPENCLAW", + ...(opts.rerank && { rerank: true }), }); return results as unknown as Record[]; }, diff --git a/integrations/openclaw/recall.ts b/integrations/openclaw/recall.ts index 90a5c68a70..4bde8cddcc 100644 --- a/integrations/openclaw/recall.ts +++ b/integrations/openclaw/recall.ts @@ -253,13 +253,18 @@ export async function recall( const categoryOrder = recallConfig.categoryOrder ?? DEFAULT_CATEGORY_ORDER; const identityAlwaysInclude = recallConfig.identityAlwaysInclude !== false; - // Build search options (v3.0.0: keyword_search, reranking, filter_memories removed) + // Build search options. + // v3.0.0 removed keyword_search and filter_memories from the search API, + // so keywordSearch is intentionally not forwarded (it is a documented + // no-op). rerank IS still supported by the platform and is threaded + // through when the user opts in (platform-only; OSS ignores it). const searchOpts: SearchOptions = { user_id: userId, top_k: maxMemories * 2, // Over-fetch for ranking threshold, source: "OPENCLAW", }; + if (recallConfig.rerank) searchOpts.rerank = true; // Sanitize query: strip OpenClaw metadata prefix before searching const cleanQuery = sanitizeQuery(query); diff --git a/integrations/openclaw/tests/providers.test.ts b/integrations/openclaw/tests/providers.test.ts index b48f5ad5b1..a75ba475aa 100644 --- a/integrations/openclaw/tests/providers.test.ts +++ b/integrations/openclaw/tests/providers.test.ts @@ -145,7 +145,7 @@ describe("providerToBackend — search", () => { await backend.search("query"); - // v3.0.0: keyword_search, reranking removed + // v3.0.0: keyword_search removed; rerank only forwarded when requested expect(provider.search).toHaveBeenCalledWith("query", { user_id: DEFAULT_USER, top_k: undefined, @@ -154,6 +154,32 @@ describe("providerToBackend — search", () => { source: "OPENCLAW", }); }); + + it("forwards rerank to provider.search when opts.rerank is true", async () => { + const provider = createMockProvider(); + const backend = providerToBackend(provider as any, DEFAULT_USER); + + await backend.search("hello", { topK: 5, rerank: true }); + + expect(provider.search).toHaveBeenCalledWith("hello", { + user_id: DEFAULT_USER, + top_k: 5, + threshold: undefined, + filters: undefined, + source: "OPENCLAW", + rerank: true, + }); + }); + + it("omits rerank when opts.rerank is falsy", async () => { + const provider = createMockProvider(); + const backend = providerToBackend(provider as any, DEFAULT_USER); + + await backend.search("hello", { topK: 5, rerank: false }); + + const callArgs = (provider.search as any).mock.calls[0][1]; + expect(callArgs).not.toHaveProperty("rerank"); + }); }); // --------------------------------------------------------------------------- diff --git a/integrations/openclaw/types.ts b/integrations/openclaw/types.ts index 29d5523966..8f8762df49 100644 --- a/integrations/openclaw/types.ts +++ b/integrations/openclaw/types.ts @@ -52,6 +52,9 @@ export interface SearchOptions { categories?: string[]; filters?: Record; source?: string; + /** Platform-only: request Mem0 Advanced Retrieval reranking of results. + * Ignored in open-source mode (the OSS SDK has no reranker). */ + rerank?: boolean; } // ============================================================================ @@ -80,7 +83,13 @@ export interface SkillsConfig { strategy?: "always" | "smart" | "manual"; tokenBudget?: number; maxMemories?: number; + /** Platform-only. When true, threads `rerank` into the Mem0 search + * payload so the platform applies Advanced Retrieval reranking on top + * of the plugin's local ranking. No effect in open-source mode. */ rerank?: boolean; + /** @deprecated No-op since Mem0 v3 removed keyword search from the + * search API. Kept for backwards compatibility; setting it has no + * effect. Will be removed in a future major version. */ keywordSearch?: boolean; filterMemories?: boolean; threshold?: number;