diff --git a/cli/node/package.json b/cli/node/package.json index 15a9643d6..c7182376b 100644 --- a/cli/node/package.json +++ b/cli/node/package.json @@ -1,6 +1,6 @@ { "name": "@mem0/cli", - "version": "0.2.3", + "version": "0.2.4", "description": "The official CLI for mem0 — the memory layer for AI agents", "type": "module", "bin": { diff --git a/cli/node/src/backend/base.ts b/cli/node/src/backend/base.ts index c0c9ae4f9..be1a0ce1f 100644 --- a/cli/node/src/backend/base.ts +++ b/cli/node/src/backend/base.ts @@ -15,7 +15,6 @@ export interface AddOptions { infer?: boolean; expires?: string; categories?: string[]; - enableGraph?: boolean; } export interface SearchOptions { @@ -29,7 +28,6 @@ export interface SearchOptions { keyword?: boolean; filters?: Record; fields?: string[]; - enableGraph?: boolean; } export interface ListOptions { @@ -42,7 +40,6 @@ export interface ListOptions { category?: string; after?: string; before?: string; - enableGraph?: boolean; } export interface DeleteOptions { diff --git a/cli/node/src/backend/platform.ts b/cli/node/src/backend/platform.ts index 7ac121948..3d7b012ad 100644 --- a/cli/node/src/backend/platform.ts +++ b/cli/node/src/backend/platform.ts @@ -115,10 +115,9 @@ export class PlatformBackend implements Backend { if (opts.infer === false) payload.infer = false; if (opts.expires) payload.expiration_date = opts.expires; if (opts.categories) payload.categories = opts.categories; - if (opts.enableGraph) payload.enable_graph = true; payload.source = "CLI"; - return (await this._request("POST", "/v1/memories/", { + return (await this._request("POST", "/v3/memories/add/", { json: payload, })) as Record; } @@ -176,10 +175,9 @@ export class PlatformBackend implements Backend { if (opts.rerank) payload.rerank = true; if (opts.keyword) payload.keyword_search = true; if (opts.fields) payload.fields = opts.fields; - if (opts.enableGraph) payload.enable_graph = true; payload.source = "CLI"; - const result = (await this._request("POST", "/v2/memories/search/", { + const result = (await this._request("POST", "/v3/memories/search/", { json: payload, })) as unknown; if (Array.isArray(result)) return result; @@ -227,10 +225,9 @@ export class PlatformBackend implements Backend { extraFilters: Object.keys(extra).length > 0 ? extra : undefined, }); if (apiFilters) payload.filters = apiFilters; - if (opts.enableGraph) payload.enable_graph = true; payload.source = "CLI"; - const result = (await this._request("POST", "/v2/memories/", { + const result = (await this._request("POST", "/v3/memories/", { json: payload, params, })) as unknown; diff --git a/cli/node/src/commands/config.ts b/cli/node/src/commands/config.ts index 9e11f8608..a4755a2e1 100644 --- a/cli/node/src/commands/config.ts +++ b/cli/node/src/commands/config.ts @@ -29,7 +29,6 @@ export function cmdConfigShow(opts: { output?: string } = {}): void { agent_id: config.defaults.agentId || null, app_id: config.defaults.appId || null, run_id: config.defaults.runId || null, - enable_graph: config.defaults.enableGraph, }, platform: { api_key: redactKey(config.platform.apiKey), @@ -56,7 +55,6 @@ export function cmdConfigShow(opts: { output?: string } = {}): void { ]); table.push(["defaults.app_id", config.defaults.appId || dim("(not set)")]); table.push(["defaults.run_id", config.defaults.runId || dim("(not set)")]); - table.push(["defaults.enable_graph", String(config.defaults.enableGraph)]); table.push(["", ""]); // Platform diff --git a/cli/node/src/commands/memory.ts b/cli/node/src/commands/memory.ts index 8ce6169b4..dd3a08211 100644 --- a/cli/node/src/commands/memory.ts +++ b/cli/node/src/commands/memory.ts @@ -49,7 +49,6 @@ export async function cmdAdd( noInfer: boolean; expires?: string; categories?: string; - enableGraph: boolean; output: string; }, ): Promise { @@ -140,7 +139,6 @@ export async function cmdAdd( infer: !opts.noInfer, expires: opts.expires, categories: cats, - enableGraph: opts.enableGraph, }); }); } catch (e) { @@ -225,7 +223,6 @@ export async function cmdSearch( keyword: boolean; filterJson?: string; fields?: string; - enableGraph: boolean; output: string; }, ): Promise { @@ -274,7 +271,6 @@ export async function cmdSearch( keyword: opts.keyword, filters, fields: fieldList, - enableGraph: opts.enableGraph, }); }); } catch (e) { @@ -368,7 +364,6 @@ export async function cmdList( category?: string; after?: string; before?: string; - enableGraph: boolean; output: string; }, ): Promise { @@ -396,7 +391,6 @@ export async function cmdList( category: opts.category, after: opts.after, before: opts.before, - enableGraph: opts.enableGraph, }); }); } catch (e) { diff --git a/cli/node/src/config.ts b/cli/node/src/config.ts index 8cbd8d0d4..29a0d7157 100644 --- a/cli/node/src/config.ts +++ b/cli/node/src/config.ts @@ -28,7 +28,6 @@ export interface DefaultsConfig { agentId: string; appId: string; runId: string; - enableGraph: boolean; } export interface TelemetryConfig { @@ -50,7 +49,6 @@ export function createDefaultConfig(): Mem0Config { agentId: "", appId: "", runId: "", - enableGraph: false, }, platform: { apiKey: "", @@ -87,8 +85,6 @@ export function loadConfig(): Mem0Config { config.defaults.agentId = defaults.agent_id ?? ""; config.defaults.appId = defaults.app_id ?? ""; config.defaults.runId = defaults.run_id ?? ""; - config.defaults.enableGraph = defaults.enable_graph ?? false; - const telemetry = data.telemetry ?? {}; config.telemetry.anonymousId = telemetry.anonymous_id ?? ""; } @@ -104,12 +100,6 @@ export function loadConfig(): Mem0Config { config.defaults.agentId = process.env.MEM0_AGENT_ID; if (process.env.MEM0_APP_ID) config.defaults.appId = process.env.MEM0_APP_ID; if (process.env.MEM0_RUN_ID) config.defaults.runId = process.env.MEM0_RUN_ID; - if (process.env.MEM0_ENABLE_GRAPH) { - config.defaults.enableGraph = ["true", "1", "yes"].includes( - process.env.MEM0_ENABLE_GRAPH.toLowerCase(), - ); - } - return config; } @@ -123,7 +113,6 @@ export function saveConfig(config: Mem0Config): void { agent_id: config.defaults.agentId, app_id: config.defaults.appId, run_id: config.defaults.runId, - enable_graph: config.defaults.enableGraph, }, platform: { api_key: config.platform.apiKey, @@ -154,7 +143,6 @@ const KEY_MAP: Record = { "defaults.agent_id": ["defaults", "agentId"], "defaults.app_id": ["defaults", "appId"], "defaults.run_id": ["defaults", "runId"], - "defaults.enable_graph": ["defaults", "enableGraph"], // Short-form aliases api_key: ["platform", "apiKey"], base_url: ["platform", "baseUrl"], @@ -163,7 +151,6 @@ const KEY_MAP: Record = { agent_id: ["defaults", "agentId"], app_id: ["defaults", "appId"], run_id: ["defaults", "runId"], - enable_graph: ["defaults", "enableGraph"], }; export function getNestedValue(config: Mem0Config, dottedKey: string): unknown { diff --git a/cli/node/src/index.ts b/cli/node/src/index.ts index 41de42cfd..30db1209b 100644 --- a/cli/node/src/index.ts +++ b/cli/node/src/index.ts @@ -134,18 +134,6 @@ function resolveIds( }; } -/** - * Resolve graph tri-state: --no-graph > --graph > config default. - */ -function resolveGraph( - config: Mem0Config, - opts: { graph?: boolean; noGraph?: boolean }, -): boolean { - if (opts.noGraph) return false; - if (opts.graph) return true; - return config.defaults.enableGraph; -} - // ── Main program ────────────────────────────────────────────────────────── program @@ -236,8 +224,6 @@ program .option("--no-infer", "Skip inference, store raw.") .option("--expires ", "Expiration date (YYYY-MM-DD).") .option("--categories ", "Categories (JSON array or comma-separated).") - .option("--graph", "Enable graph memory extraction.", false) - .option("--no-graph", "Disable graph memory extraction.") .option("-o, --output ", "Output format: text, json, quiet.", "text") .option("--api-key ", "Override API key.") .option("--base-url ", "Override API base URL.") @@ -253,9 +239,8 @@ program opts.baseUrl, ); const ids = resolveIds(config, opts); - const enableGraph = resolveGraph(config, opts); const output = isAgent ? "agent" : opts.output; - await cmdAdd(backend, text, { ...ids, ...opts, enableGraph, output }); + await cmdAdd(backend, text, { ...ids, ...opts, output }); }); // ── Memory: search ──────────────────────────────────────────────────────── @@ -285,8 +270,6 @@ program .option("--keyword", "Use keyword search.", false) .option("--filter ", "Advanced filter expression (JSON).") .option("--fields ", "Specific fields to return (comma-separated).") - .option("--graph", "Enable graph in search.", false) - .option("--no-graph", "Disable graph in search.") .option("-o, --output ", "Output: text, json, table.", "text") .option("--api-key ", "Override API key.") .option("--base-url ", "Override API base URL.") @@ -310,7 +293,6 @@ program opts.baseUrl, ); const ids = resolveIds(config, opts); - const enableGraph = resolveGraph(config, opts); const output = isAgent ? "agent" : opts.output; await cmdSearch(backend, resolvedQuery, { ...ids, @@ -320,7 +302,6 @@ program keyword: opts.keyword, filterJson: opts.filter, fields: opts.fields, - enableGraph, output, }); }); @@ -364,8 +345,6 @@ program .option("--category ", "Filter by category.") .option("--after ", "Created after (YYYY-MM-DD).") .option("--before ", "Created before (YYYY-MM-DD).") - .option("--graph", "Enable graph in listing.", false) - .option("--no-graph", "Disable graph in listing.") .option("-o, --output ", "Output: text, json, table.", "table") .option("--api-key ", "Override API key.") .option("--base-url ", "Override API base URL.") @@ -381,7 +360,6 @@ program opts.baseUrl, ); const ids = resolveIds(config, opts); - const enableGraph = resolveGraph(config, opts); const output = isAgent ? "agent" : opts.output; await cmdList(backend, { ...ids, @@ -390,7 +368,6 @@ program category: opts.category, after: opts.after, before: opts.before, - enableGraph, output, }); }); diff --git a/cli/node/tests/cli-integration.test.ts b/cli/node/tests/cli-integration.test.ts index 82d9e108f..630cfec4b 100644 --- a/cli/node/tests/cli-integration.test.ts +++ b/cli/node/tests/cli-integration.test.ts @@ -107,22 +107,22 @@ describe("CLI Integration — help and version", () => { expect(result.exitCode).toBe(0); }); - it("add help has --graph flag", () => { + it("add help has --output flag", () => { const result = run(["add", "--help"]); expect(result.exitCode).toBe(0); - expect(result.stdout).toContain("--graph"); + expect(result.stdout).toContain("--output"); }); - it("search help has --graph flag", () => { + it("search help has --rerank flag", () => { const result = run(["search", "--help"]); expect(result.exitCode).toBe(0); - expect(result.stdout).toContain("--graph"); + expect(result.stdout).toContain("--rerank"); }); - it("list help has --graph flag", () => { + it("list help has --category flag", () => { const result = run(["list", "--help"]); expect(result.exitCode).toBe(0); - expect(result.stdout).toContain("--graph"); + expect(result.stdout).toContain("--category"); }); }); diff --git a/cli/node/tests/commands.test.ts b/cli/node/tests/commands.test.ts index f77ff3aa8..0d67a03af 100644 --- a/cli/node/tests/commands.test.ts +++ b/cli/node/tests/commands.test.ts @@ -42,7 +42,7 @@ describe("cmdAdd", () => { userId: "alice", immutable: false, noInfer: false, - enableGraph: false, + output: "text", }); expect(mockBackend.add).toHaveBeenCalledOnce(); @@ -55,7 +55,7 @@ describe("cmdAdd", () => { messages: JSON.stringify([{ role: "user", content: "I love Python" }]), immutable: false, noInfer: false, - enableGraph: false, + output: "text", }); expect(mockBackend.add).toHaveBeenCalledOnce(); @@ -67,7 +67,7 @@ describe("cmdAdd", () => { userId: "alice", immutable: false, noInfer: false, - enableGraph: false, + output: "json", }); expect(output).toContain("results"); @@ -79,7 +79,7 @@ describe("cmdAdd", () => { userId: "alice", immutable: false, noInfer: false, - enableGraph: false, + output: "quiet", }); expect(output).not.toContain("dark mode"); @@ -101,7 +101,7 @@ describe("cmdAdd deduplicates PENDING", () => { userId: "alice", immutable: false, noInfer: false, - enableGraph: false, + output: "text", }); expect(output.match(/Queued/g)?.length).toBe(1); @@ -114,7 +114,7 @@ describe("cmdAdd deduplicates PENDING", () => { userId: "alice", immutable: false, noInfer: false, - enableGraph: false, + output: "json", }); const data = JSON.parse(output); @@ -130,7 +130,7 @@ describe("cmdAdd deduplicates PENDING", () => { userId: "alice", immutable: false, noInfer: false, - enableGraph: false, + output: "agent", }); const data = JSON.parse(output); @@ -148,7 +148,7 @@ describe("cmdSearch", () => { threshold: 0.3, rerank: false, keyword: false, - enableGraph: false, + output: "text", }); expect(output).toContain("Found 2"); @@ -162,7 +162,7 @@ describe("cmdSearch", () => { threshold: 0.3, rerank: false, keyword: false, - enableGraph: false, + output: "json", }); expect(output).toContain("memory"); @@ -177,7 +177,7 @@ describe("cmdSearch", () => { threshold: 0.3, rerank: false, keyword: false, - enableGraph: false, + output: "text", }); expect(errOutput).toContain("No memories found"); @@ -205,7 +205,7 @@ describe("cmdList", () => { userId: "alice", page: 1, pageSize: 100, - enableGraph: false, + output: "table", }); expect(output).toContain("dark mode"); @@ -218,7 +218,7 @@ describe("cmdList", () => { userId: "alice", page: 1, pageSize: 100, - enableGraph: false, + output: "text", }); expect(errOutput).toContain("No memories found"); @@ -316,7 +316,7 @@ describe("agent mode", () => { userId: "alice", immutable: false, noInfer: false, - enableGraph: false, + output: "agent", }); const parsed = JSON.parse(output.trim()); @@ -336,7 +336,7 @@ describe("agent mode", () => { threshold: 0.3, rerank: false, keyword: false, - enableGraph: false, + output: "agent", }); const parsed = JSON.parse(output.trim()); @@ -361,7 +361,7 @@ describe("agent mode", () => { userId: "alice", page: 1, pageSize: 100, - enableGraph: false, + output: "agent", }); const parsed = JSON.parse(output.trim()); diff --git a/cli/node/tests/config.test.ts b/cli/node/tests/config.test.ts index 9c7fdf8a7..20c36af8d 100644 --- a/cli/node/tests/config.test.ts +++ b/cli/node/tests/config.test.ts @@ -64,7 +64,6 @@ describe("createDefaultConfig", () => { expect(config.platform.baseUrl).toBe("https://api.mem0.ai"); expect(config.platform.apiKey).toBe(""); expect(config.defaults.userId).toBe(""); - expect(config.defaults.enableGraph).toBe(false); }); }); @@ -105,9 +104,4 @@ describe("setNestedValue", () => { expect(config.defaults.userId).toBe("bob"); }); - it("coerces boolean for enable_graph", () => { - const config = createDefaultConfig(); - expect(setNestedValue(config, "defaults.enable_graph", "true")).toBe(true); - expect(config.defaults.enableGraph).toBe(true); - }); }); diff --git a/cli/python/pyproject.toml b/cli/python/pyproject.toml index 7523d5506..66176e676 100644 --- a/cli/python/pyproject.toml +++ b/cli/python/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "mem0-cli" -version = "0.2.3" +version = "0.2.4" description = "The official CLI for mem0 — the memory layer for AI agents" readme = "README.md" license = "Apache-2.0" diff --git a/cli/python/src/mem0_cli/__init__.py b/cli/python/src/mem0_cli/__init__.py index 33fa6b345..d8f12d640 100644 --- a/cli/python/src/mem0_cli/__init__.py +++ b/cli/python/src/mem0_cli/__init__.py @@ -1,3 +1,3 @@ """mem0 CLI — the command-line interface for the mem0 memory layer.""" -__version__ = "0.2.3" +__version__ = "0.2.4" diff --git a/cli/python/src/mem0_cli/app.py b/cli/python/src/mem0_cli/app.py index bdfb75647..ef0aed5ab 100644 --- a/cli/python/src/mem0_cli/app.py +++ b/cli/python/src/mem0_cli/app.py @@ -267,8 +267,6 @@ def add( categories: str | None = typer.Option( None, "--categories", help="Categories (JSON array or comma-separated)." ), - graph: bool = typer.Option(False, "--graph", help="Enable graph memory extraction."), - no_graph: bool = typer.Option(False, "--no-graph", help="Disable graph memory extraction."), output: str = typer.Option( "text", "--output", "-o", help="Output format: text, json, quiet.", rich_help_panel="Output" ), @@ -295,13 +293,6 @@ def add( backend, config = _get_backend_and_config(api_key, base_url) ids = _resolve_ids(config, user_id=user_id, agent_id=agent_id, app_id=app_id, run_id=run_id) - if no_graph: - graph_enabled = False - elif graph: - graph_enabled = True - else: - graph_enabled = config.defaults.enable_graph - cmd_add( backend, text, @@ -313,7 +304,6 @@ def add( no_infer=no_infer, expires=expires, categories=categories, - enable_graph=graph_enabled, output=output, ) @@ -357,12 +347,6 @@ def search( help="Specific fields to return (comma-separated).", rich_help_panel="Search", ), - graph: bool = typer.Option( - False, "--graph", help="Enable graph in search.", rich_help_panel="Search" - ), - no_graph: bool = typer.Option( - False, "--no-graph", help="Disable graph in search.", rich_help_panel="Search" - ), output: str = typer.Option( "text", "--output", "-o", help="Output: text, json, table.", rich_help_panel="Output" ), @@ -396,13 +380,6 @@ def search( backend, config = _get_backend_and_config(api_key, base_url) ids = _resolve_ids(config, user_id=user_id, agent_id=agent_id, app_id=app_id, run_id=run_id) - if no_graph: - graph_enabled = False - elif graph: - graph_enabled = True - else: - graph_enabled = config.defaults.enable_graph - cmd_search( backend, query, @@ -413,7 +390,6 @@ def search( keyword=keyword, filter_json=filter_json, fields=fields, - enable_graph=graph_enabled, output=output, ) @@ -480,12 +456,6 @@ def list_cmd( before: str | None = typer.Option( None, "--before", help="Created before (YYYY-MM-DD).", rich_help_panel="Filters" ), - graph: bool = typer.Option( - False, "--graph", help="Enable graph in listing.", rich_help_panel="Filters" - ), - no_graph: bool = typer.Option( - False, "--no-graph", help="Disable graph in listing.", rich_help_panel="Filters" - ), output: str = typer.Option( "table", "--output", "-o", help="Output: text, json, table.", rich_help_panel="Output" ), @@ -511,13 +481,6 @@ def list_cmd( backend, config = _get_backend_and_config(api_key, base_url) ids = _resolve_ids(config, user_id=user_id, agent_id=agent_id, app_id=app_id, run_id=run_id) - if no_graph: - graph_enabled = False - elif graph: - graph_enabled = True - else: - graph_enabled = config.defaults.enable_graph - cmd_list( backend, **ids, @@ -526,7 +489,6 @@ def list_cmd( category=category, after=after, before=before, - enable_graph=graph_enabled, output=output, ) diff --git a/cli/python/src/mem0_cli/backend/base.py b/cli/python/src/mem0_cli/backend/base.py index c74b6ca33..183e0bfa1 100644 --- a/cli/python/src/mem0_cli/backend/base.py +++ b/cli/python/src/mem0_cli/backend/base.py @@ -26,7 +26,6 @@ class Backend(ABC): infer: bool = True, expires: str | None = None, categories: list[str] | None = None, - enable_graph: bool = False, ) -> dict: ... @abstractmethod @@ -44,7 +43,6 @@ class Backend(ABC): keyword: bool = False, filters: dict | None = None, fields: list[str] | None = None, - enable_graph: bool = False, ) -> list[dict]: ... @abstractmethod @@ -63,7 +61,6 @@ class Backend(ABC): category: str | None = None, after: str | None = None, before: str | None = None, - enable_graph: bool = False, ) -> list[dict]: ... @abstractmethod diff --git a/cli/python/src/mem0_cli/backend/platform.py b/cli/python/src/mem0_cli/backend/platform.py index 9da6a2b58..da1cb47f7 100644 --- a/cli/python/src/mem0_cli/backend/platform.py +++ b/cli/python/src/mem0_cli/backend/platform.py @@ -64,7 +64,6 @@ class PlatformBackend(Backend): infer: bool = True, expires: str | None = None, categories: list[str] | None = None, - enable_graph: bool = False, ) -> dict: payload: dict[str, Any] = {} @@ -91,11 +90,9 @@ class PlatformBackend(Backend): payload["expiration_date"] = expires if categories: payload["categories"] = categories - if enable_graph: - payload["enable_graph"] = True payload["source"] = "CLI" - return self._request("POST", "/v1/memories/", json=payload) + return self._request("POST", "/v3/memories/add/", json=payload) def _build_filters( self, @@ -106,7 +103,7 @@ class PlatformBackend(Backend): run_id: str | None = None, extra_filters: dict | None = None, ) -> dict | None: - """Build a filters dict for v2 API endpoints. + """Build a filters dict for v3 API endpoints. Entity IDs are ANDed (all provided IDs must match). Extra filters (date ranges, categories) are also ANDed. @@ -152,7 +149,6 @@ class PlatformBackend(Backend): keyword: bool = False, filters: dict | None = None, fields: list[str] | None = None, - enable_graph: bool = False, ) -> list[dict]: payload: dict[str, Any] = {"query": query, "top_k": top_k, "threshold": threshold} @@ -171,11 +167,9 @@ class PlatformBackend(Backend): payload["keyword_search"] = True if fields: payload["fields"] = fields - if enable_graph: - payload["enable_graph"] = True payload["source"] = "CLI" - result = self._request("POST", "/v2/memories/search/", json=payload) + result = self._request("POST", "/v3/memories/search/", json=payload) return ( result if isinstance(result, list) @@ -197,12 +191,11 @@ class PlatformBackend(Backend): category: str | None = None, after: str | None = None, before: str | None = None, - enable_graph: bool = False, ) -> list[dict]: payload: dict[str, Any] = {} params = {"page": str(page), "page_size": str(page_size)} - # Build filters for v2 API — entity IDs and date filters go inside "filters" + # Build filters — entity IDs and date filters go inside "filters" extra: dict[str, Any] = {} if category: extra["categories"] = {"contains": category} @@ -220,11 +213,9 @@ class PlatformBackend(Backend): ) if api_filters: payload["filters"] = api_filters - if enable_graph: - payload["enable_graph"] = True payload["source"] = "CLI" - result = self._request("POST", "/v2/memories/", json=payload, params=params) + result = self._request("POST", "/v3/memories/", json=payload, params=params) return ( result if isinstance(result, list) diff --git a/cli/python/src/mem0_cli/commands/config_cmd.py b/cli/python/src/mem0_cli/commands/config_cmd.py index 1bfe090e6..965643fef 100644 --- a/cli/python/src/mem0_cli/commands/config_cmd.py +++ b/cli/python/src/mem0_cli/commands/config_cmd.py @@ -39,7 +39,6 @@ def cmd_config_show(*, output: str = "text") -> None: "agent_id": config.defaults.agent_id or None, "app_id": config.defaults.app_id or None, "run_id": config.defaults.run_id or None, - "enable_graph": config.defaults.enable_graph, }, "platform": { "api_key": redact_key(config.platform.api_key), @@ -73,10 +72,6 @@ def cmd_config_show(*, output: str = "text") -> None: "defaults.run_id", config.defaults.run_id or f"[{DIM_COLOR}](not set)[/]", ) - table.add_row( - "defaults.enable_graph", - str(config.defaults.enable_graph).lower(), - ) table.add_row("", "") # Platform diff --git a/cli/python/src/mem0_cli/commands/memory.py b/cli/python/src/mem0_cli/commands/memory.py index 779447a0e..7e9ace6e4 100644 --- a/cli/python/src/mem0_cli/commands/memory.py +++ b/cli/python/src/mem0_cli/commands/memory.py @@ -62,7 +62,6 @@ def cmd_add( no_infer: bool, expires: str | None, categories: str | None, - enable_graph: bool = False, output: str = "text", ) -> None: """Add a memory.""" @@ -145,7 +144,6 @@ def cmd_add( infer=not no_infer, expires=expires, categories=cats, - enable_graph=enable_graph, ) except Exception as e: ts.error_msg = str(e) @@ -226,7 +224,6 @@ def cmd_search( keyword: bool, filter_json: str | None, fields: str | None, - enable_graph: bool = False, output: str = "text", ) -> None: """Search memories.""" @@ -269,7 +266,6 @@ def cmd_search( keyword=keyword, filters=filters, fields=field_list, - enable_graph=enable_graph, ) except Exception as e: print_error(err_console, str(e)) @@ -356,7 +352,6 @@ def cmd_list( category: str | None, after: str | None, before: str | None, - enable_graph: bool = False, output: str = "table", ) -> None: """List memories.""" @@ -385,7 +380,6 @@ def cmd_list( category=category, after=after, before=before, - enable_graph=enable_graph, ) except Exception as e: print_error(err_console, str(e)) diff --git a/cli/python/src/mem0_cli/config.py b/cli/python/src/mem0_cli/config.py index 88a804f2c..ebf81fc80 100644 --- a/cli/python/src/mem0_cli/config.py +++ b/cli/python/src/mem0_cli/config.py @@ -36,7 +36,6 @@ class DefaultsConfig: agent_id: str = "" app_id: str = "" run_id: str = "" - enable_graph: bool = False @dataclass @@ -60,7 +59,6 @@ SHORT_KEY_ALIASES: dict[str, str] = { "agent_id": "defaults.agent_id", "app_id": "defaults.app_id", "run_id": "defaults.run_id", - "enable_graph": "defaults.enable_graph", } @@ -91,8 +89,6 @@ def load_config() -> Mem0Config: config.defaults.agent_id = defaults.get("agent_id", "") config.defaults.app_id = defaults.get("app_id", "") config.defaults.run_id = defaults.get("run_id", "") - config.defaults.enable_graph = defaults.get("enable_graph", False) - telemetry = data.get("telemetry", {}) config.telemetry.anonymous_id = telemetry.get("anonymous_id", "") @@ -121,10 +117,6 @@ def load_config() -> Mem0Config: if env_run_id: config.defaults.run_id = env_run_id - env_graph = os.environ.get("MEM0_ENABLE_GRAPH") - if env_graph: - config.defaults.enable_graph = env_graph.lower() in ("true", "1", "yes") - return config @@ -139,7 +131,6 @@ def save_config(config: Mem0Config) -> None: "agent_id": config.defaults.agent_id, "app_id": config.defaults.app_id, "run_id": config.defaults.run_id, - "enable_graph": config.defaults.enable_graph, }, "platform": { "api_key": config.platform.api_key, diff --git a/cli/python/tests/test_cli_integration.py b/cli/python/tests/test_cli_integration.py index f5e176fe9..ea6607201 100644 --- a/cli/python/tests/test_cli_integration.py +++ b/cli/python/tests/test_cli_integration.py @@ -224,24 +224,13 @@ class TestCLIIsolated: class TestCLINewFeatures: - """Tests for MCP parity features: --graph, --limit, entities delete.""" + """Tests for MCP parity features: --limit, entities delete.""" - def test_add_help_has_graph(self): - result = _run(["add", "--help"]) - assert result.returncode == 0 - assert "--graph" in result.stdout - - def test_search_help_has_graph_and_limit(self): + def test_search_help_has_limit(self): result = _run(["search", "--help"]) assert result.returncode == 0 - assert "--graph" in result.stdout assert "--limit" in result.stdout - def test_list_help_has_graph(self): - result = _run(["list", "--help"]) - assert result.returncode == 0 - assert "--graph" in result.stdout - def test_delete_entity_via_delete_flag(self): """delete --entity should appear in help output.""" result = _run(["delete", "--help"]) diff --git a/cli/python/tests/test_commands.py b/cli/python/tests/test_commands.py index 971a2d597..4f8036623 100644 --- a/cli/python/tests/test_commands.py +++ b/cli/python/tests/test_commands.py @@ -997,85 +997,6 @@ class TestEntitiesDeleteCommand: mock_backend.delete_entities.assert_not_called() -class TestEnableGraph: - def test_add_with_graph(self, mock_backend): - console, _buf = _make_console() - err_console, _err_buf = _make_err_console() - with ( - patch("mem0_cli.commands.memory.console", console), - patch("mem0_cli.commands.memory.err_console", err_console), - ): - cmd_add( - mock_backend, - "test", - user_id="alice", - agent_id=None, - app_id=None, - run_id=None, - messages=None, - file=None, - metadata=None, - immutable=False, - no_infer=False, - expires=None, - categories=None, - enable_graph=True, - output="text", - ) - call_kwargs = mock_backend.add.call_args - assert call_kwargs.kwargs.get("enable_graph") is True - - def test_search_with_graph(self, mock_backend): - console, _buf = _make_console() - err_console, _err_buf = _make_err_console() - with ( - patch("mem0_cli.commands.memory.console", console), - patch("mem0_cli.commands.memory.err_console", err_console), - ): - cmd_search( - mock_backend, - "test", - user_id="alice", - agent_id=None, - app_id=None, - run_id=None, - top_k=10, - threshold=0.3, - rerank=False, - keyword=False, - filter_json=None, - fields=None, - enable_graph=True, - output="text", - ) - call_kwargs = mock_backend.search.call_args - assert call_kwargs.kwargs.get("enable_graph") is True - - def test_list_with_graph(self, mock_backend): - console, _buf = _make_console() - err_console, _err_buf = _make_err_console() - with ( - patch("mem0_cli.commands.memory.console", console), - patch("mem0_cli.commands.memory.err_console", err_console), - ): - cmd_list( - mock_backend, - user_id="alice", - agent_id=None, - app_id=None, - run_id=None, - page=1, - page_size=100, - category=None, - after=None, - before=None, - enable_graph=True, - output="table", - ) - call_kwargs = mock_backend.list_memories.call_args - assert call_kwargs.kwargs.get("enable_graph") is True - - class TestEventCommands: def test_event_list_table(self, mock_backend): console, buf = _make_console() diff --git a/cli/python/tests/test_config.py b/cli/python/tests/test_config.py index 1de991ac6..48db01481 100644 --- a/cli/python/tests/test_config.py +++ b/cli/python/tests/test_config.py @@ -121,46 +121,6 @@ class TestConfig: assert config.defaults.agent_id == "" assert config.defaults.app_id == "" assert config.defaults.run_id == "" - assert config.defaults.enable_graph is False - - def test_enable_graph_save_and_load(self, isolate_config): - config = Mem0Config() - config.defaults.enable_graph = True - save_config(config) - loaded = load_config() - assert loaded.defaults.enable_graph is True - - def test_enable_graph_env_var_true(self, isolate_config, monkeypatch): - monkeypatch.setenv("MEM0_ENABLE_GRAPH", "true") - loaded = load_config() - assert loaded.defaults.enable_graph is True - - def test_enable_graph_env_var_false(self, isolate_config, monkeypatch): - config = Mem0Config() - config.defaults.enable_graph = True - save_config(config) - monkeypatch.setenv("MEM0_ENABLE_GRAPH", "false") - loaded = load_config() - assert loaded.defaults.enable_graph is False - - def test_backward_compat_no_enable_graph_key(self, isolate_config): - """Old config files without 'enable_graph' key should default to False.""" - import json - - from mem0_cli.config import CONFIG_FILE, ensure_config_dir - - ensure_config_dir() - data = { - "version": 1, - "defaults": {"user_id": "alice"}, - "platform": {"api_key": "m0-test", "base_url": "https://api.mem0.ai"}, - } - with open(CONFIG_FILE, "w") as f: - json.dump(data, f) - - loaded = load_config() - assert loaded.defaults.enable_graph is False - assert loaded.defaults.user_id == "alice" class TestNestedAccess: @@ -192,11 +152,6 @@ class TestNestedAccess: assert set_nested_value(config, "defaults.user_id", "bob") assert config.defaults.user_id == "bob" - def test_set_defaults_enable_graph(self): - config = Mem0Config() - assert set_nested_value(config, "defaults.enable_graph", "true") - assert config.defaults.enable_graph is True - class TestResolveIds: def test_cli_flag_overrides_default(self): diff --git a/docs/changelog/sdk.mdx b/docs/changelog/sdk.mdx index 30b58e675..930d5157e 100644 --- a/docs/changelog/sdk.mdx +++ b/docs/changelog/sdk.mdx @@ -1269,6 +1269,16 @@ See the [TypeScript SDK migration guide](https://docs.mem0.ai/migration/ts-v2-to + + +**New Features:** +- **V3 API Routes:** Migrated `add`, `search`, and `list` commands from v1/v2 to v3 API endpoints — `POST /v3/memories/add/`, `POST /v3/memories/search/`, `POST /v3/memories/`. Aligns both CLIs with the Python and TypeScript SDKs which already use v3 ([#4916](https://github.com/mem0ai/mem0/pull/4916)) + +**Breaking Changes:** +- **`--graph` / `--no-graph` removed:** The `enable_graph` config option, `--graph` and `--no-graph` CLI flags, and `MEM0_ENABLE_GRAPH` environment variable have been removed from both CLIs. Graph memory is now a project-level setting on the Platform ([#4916](https://github.com/mem0ai/mem0/pull/4916)) + + + **Bug Fixes:**