mem0-cli 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mem0_cli/__init__.py +3 -0
- mem0_cli/__main__.py +5 -0
- mem0_cli/app.py +1021 -0
- mem0_cli/backend/__init__.py +5 -0
- mem0_cli/backend/base.py +113 -0
- mem0_cli/backend/platform.py +325 -0
- mem0_cli/branding.py +130 -0
- mem0_cli/commands/__init__.py +1 -0
- mem0_cli/commands/config_cmd.py +108 -0
- mem0_cli/commands/entities.py +133 -0
- mem0_cli/commands/init_cmd.py +195 -0
- mem0_cli/commands/memory.py +469 -0
- mem0_cli/commands/utils.py +142 -0
- mem0_cli/config.py +176 -0
- mem0_cli/output.py +242 -0
- mem0_cli-0.1.0.dist-info/METADATA +57 -0
- mem0_cli-0.1.0.dist-info/RECORD +19 -0
- mem0_cli-0.1.0.dist-info/WHEEL +4 -0
- mem0_cli-0.1.0.dist-info/entry_points.txt +2 -0
mem0_cli/app.py
ADDED
|
@@ -0,0 +1,1021 @@
|
|
|
1
|
+
"""Main CLI application — the entrypoint for `mem0`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json as _json
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
|
|
12
|
+
from mem0_cli import __version__
|
|
13
|
+
from mem0_cli.branding import BRAND_COLOR, print_error
|
|
14
|
+
|
|
15
|
+
console = Console()
|
|
16
|
+
err_console = Console(stderr=True)
|
|
17
|
+
|
|
18
|
+
# ── Main app ──────────────────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
app = typer.Typer(
|
|
21
|
+
name="mem0",
|
|
22
|
+
help=f"◆ Mem0 CLI v{__version__} · Python SDK\n\n The Memory Layer for AI Agents",
|
|
23
|
+
no_args_is_help=True,
|
|
24
|
+
rich_markup_mode="rich",
|
|
25
|
+
pretty_exceptions_enable=False,
|
|
26
|
+
add_completion=False,
|
|
27
|
+
subcommand_metavar="<command> [options]",
|
|
28
|
+
options_metavar="",
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# ── Sub-groups (defined here, registered later to control help ordering) ──
|
|
32
|
+
|
|
33
|
+
config_app = typer.Typer(
|
|
34
|
+
name="config",
|
|
35
|
+
help="Manage mem0 configuration.",
|
|
36
|
+
no_args_is_help=True,
|
|
37
|
+
rich_markup_mode="rich",
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
entity_app = typer.Typer(
|
|
41
|
+
name="entity",
|
|
42
|
+
help="Manage entities.",
|
|
43
|
+
no_args_is_help=True,
|
|
44
|
+
rich_markup_mode="rich",
|
|
45
|
+
)
|
|
46
|
+
# entity_app registered after Memory commands to control panel ordering
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# ── Helpers ───────────────────────────────────────────────────────────────
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _get_backend_and_config(
|
|
53
|
+
api_key: str | None = None,
|
|
54
|
+
base_url: str | None = None,
|
|
55
|
+
):
|
|
56
|
+
"""Build and return the Platform backend plus the loaded config."""
|
|
57
|
+
from mem0_cli.backend import get_backend
|
|
58
|
+
from mem0_cli.config import load_config
|
|
59
|
+
|
|
60
|
+
config = load_config()
|
|
61
|
+
|
|
62
|
+
if api_key:
|
|
63
|
+
config.platform.api_key = api_key
|
|
64
|
+
if base_url:
|
|
65
|
+
config.platform.base_url = base_url
|
|
66
|
+
|
|
67
|
+
if not config.platform.api_key:
|
|
68
|
+
print_error(
|
|
69
|
+
err_console,
|
|
70
|
+
"No API key configured.",
|
|
71
|
+
hint="Run 'mem0 init' or set MEM0_API_KEY environment variable.",
|
|
72
|
+
)
|
|
73
|
+
raise typer.Exit(1)
|
|
74
|
+
|
|
75
|
+
return get_backend(config), config
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _get_backend(
|
|
79
|
+
api_key: str | None = None,
|
|
80
|
+
base_url: str | None = None,
|
|
81
|
+
):
|
|
82
|
+
"""Build and return the Platform backend."""
|
|
83
|
+
backend, _config = _get_backend_and_config(api_key, base_url)
|
|
84
|
+
return backend
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _resolve_ids(
|
|
88
|
+
config,
|
|
89
|
+
*,
|
|
90
|
+
user_id: str | None = None,
|
|
91
|
+
agent_id: str | None = None,
|
|
92
|
+
app_id: str | None = None,
|
|
93
|
+
run_id: str | None = None,
|
|
94
|
+
):
|
|
95
|
+
"""Resolve entity IDs: CLI flag > config default > None.
|
|
96
|
+
|
|
97
|
+
If any explicit ID is provided, only use explicit IDs (don't mix
|
|
98
|
+
in defaults for other entity types which would over-filter).
|
|
99
|
+
If no explicit IDs, fall back to all configured defaults.
|
|
100
|
+
"""
|
|
101
|
+
has_explicit = any([user_id, agent_id, app_id, run_id])
|
|
102
|
+
if has_explicit:
|
|
103
|
+
return {
|
|
104
|
+
"user_id": user_id or None,
|
|
105
|
+
"agent_id": agent_id or None,
|
|
106
|
+
"app_id": app_id or None,
|
|
107
|
+
"run_id": run_id or None,
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
"user_id": config.defaults.user_id or None,
|
|
111
|
+
"agent_id": config.defaults.agent_id or None,
|
|
112
|
+
"app_id": config.defaults.app_id or None,
|
|
113
|
+
"run_id": config.defaults.run_id or None,
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _read_stdin() -> str | None:
|
|
118
|
+
"""Read from stdin if it is piped (not a TTY)."""
|
|
119
|
+
if not sys.stdin.isatty():
|
|
120
|
+
return sys.stdin.read().strip() or None
|
|
121
|
+
return None
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# ── Global options (shared via callback) ──────────────────────────────────
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@app.callback(invoke_without_command=True)
|
|
128
|
+
def main_callback(
|
|
129
|
+
ctx: typer.Context,
|
|
130
|
+
version: bool = typer.Option(False, "--version", help="Show version and exit."),
|
|
131
|
+
) -> None:
|
|
132
|
+
if version:
|
|
133
|
+
from mem0_cli.commands.utils import cmd_version
|
|
134
|
+
|
|
135
|
+
cmd_version()
|
|
136
|
+
raise typer.Exit()
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
# ── Memory: add ───────────────────────────────────────────────────────────
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@app.command(rich_help_panel="Memory")
|
|
143
|
+
def add(
|
|
144
|
+
text: str | None = typer.Argument(None, help="Text content to add as a memory."),
|
|
145
|
+
user_id: str | None = typer.Option(
|
|
146
|
+
None, "--user-id", "-u", help="Scope to user.", rich_help_panel="Scope"
|
|
147
|
+
),
|
|
148
|
+
agent_id: str | None = typer.Option(
|
|
149
|
+
None, "--agent-id", help="Scope to agent.", rich_help_panel="Scope"
|
|
150
|
+
),
|
|
151
|
+
app_id: str | None = typer.Option(
|
|
152
|
+
None, "--app-id", help="Scope to app.", rich_help_panel="Scope"
|
|
153
|
+
),
|
|
154
|
+
run_id: str | None = typer.Option(
|
|
155
|
+
None, "--run-id", help="Scope to run.", rich_help_panel="Scope"
|
|
156
|
+
),
|
|
157
|
+
messages: str | None = typer.Option(None, "--messages", help="Conversation messages as JSON."),
|
|
158
|
+
file: Path | None = typer.Option(None, "--file", "-f", help="Read messages from JSON file."),
|
|
159
|
+
metadata: str | None = typer.Option(None, "--metadata", "-m", help="Custom metadata as JSON."),
|
|
160
|
+
immutable: bool = typer.Option(False, "--immutable", help="Prevent future updates."),
|
|
161
|
+
no_infer: bool = typer.Option(False, "--no-infer", help="Skip inference, store raw."),
|
|
162
|
+
expires: str | None = typer.Option(None, "--expires", help="Expiration date (YYYY-MM-DD)."),
|
|
163
|
+
categories: str | None = typer.Option(
|
|
164
|
+
None, "--categories", help="Categories (JSON array or comma-separated)."
|
|
165
|
+
),
|
|
166
|
+
graph: bool = typer.Option(False, "--graph", help="Enable graph memory extraction."),
|
|
167
|
+
no_graph: bool = typer.Option(False, "--no-graph", help="Disable graph memory extraction."),
|
|
168
|
+
output: str = typer.Option(
|
|
169
|
+
"text", "--output", "-o", help="Output format: text, json, quiet.", rich_help_panel="Output"
|
|
170
|
+
),
|
|
171
|
+
api_key: str | None = typer.Option(
|
|
172
|
+
None,
|
|
173
|
+
"--api-key",
|
|
174
|
+
help="Override API key.",
|
|
175
|
+
envvar="MEM0_API_KEY",
|
|
176
|
+
rich_help_panel="Connection",
|
|
177
|
+
),
|
|
178
|
+
base_url: str | None = typer.Option(
|
|
179
|
+
None, "--base-url", help="Override API base URL.", rich_help_panel="Connection"
|
|
180
|
+
),
|
|
181
|
+
) -> None:
|
|
182
|
+
"""Add a memory from text, messages, file, or stdin.
|
|
183
|
+
|
|
184
|
+
Examples:
|
|
185
|
+
mem0 add "I prefer dark mode" --user-id alice
|
|
186
|
+
echo "text" | mem0 add -u alice
|
|
187
|
+
mem0 add --file msgs.json -u alice -o json
|
|
188
|
+
"""
|
|
189
|
+
from mem0_cli.commands.memory import cmd_add
|
|
190
|
+
|
|
191
|
+
backend, config = _get_backend_and_config(api_key, base_url)
|
|
192
|
+
ids = _resolve_ids(config, user_id=user_id, agent_id=agent_id, app_id=app_id, run_id=run_id)
|
|
193
|
+
|
|
194
|
+
if no_graph:
|
|
195
|
+
graph_enabled = False
|
|
196
|
+
elif graph:
|
|
197
|
+
graph_enabled = True
|
|
198
|
+
else:
|
|
199
|
+
graph_enabled = config.defaults.enable_graph
|
|
200
|
+
|
|
201
|
+
cmd_add(
|
|
202
|
+
backend,
|
|
203
|
+
text,
|
|
204
|
+
**ids,
|
|
205
|
+
messages=messages,
|
|
206
|
+
file=file,
|
|
207
|
+
metadata=metadata,
|
|
208
|
+
immutable=immutable,
|
|
209
|
+
no_infer=no_infer,
|
|
210
|
+
expires=expires,
|
|
211
|
+
categories=categories,
|
|
212
|
+
enable_graph=graph_enabled,
|
|
213
|
+
output=output,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
# ── Memory: search ────────────────────────────────────────────────────────
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
@app.command(rich_help_panel="Memory")
|
|
221
|
+
def search(
|
|
222
|
+
query: str | None = typer.Argument(None, help="Search query."),
|
|
223
|
+
user_id: str | None = typer.Option(
|
|
224
|
+
None, "--user-id", "-u", help="Filter by user.", rich_help_panel="Scope"
|
|
225
|
+
),
|
|
226
|
+
agent_id: str | None = typer.Option(
|
|
227
|
+
None, "--agent-id", help="Filter by agent.", rich_help_panel="Scope"
|
|
228
|
+
),
|
|
229
|
+
app_id: str | None = typer.Option(
|
|
230
|
+
None, "--app-id", help="Filter by app.", rich_help_panel="Scope"
|
|
231
|
+
),
|
|
232
|
+
run_id: str | None = typer.Option(
|
|
233
|
+
None, "--run-id", help="Filter by run.", rich_help_panel="Scope"
|
|
234
|
+
),
|
|
235
|
+
top_k: int = typer.Option(
|
|
236
|
+
10, "--top-k", "-k", "--limit", help="Number of results.", rich_help_panel="Search"
|
|
237
|
+
),
|
|
238
|
+
threshold: float = typer.Option(
|
|
239
|
+
0.3, "--threshold", help="Minimum similarity score.", rich_help_panel="Search"
|
|
240
|
+
),
|
|
241
|
+
rerank: bool = typer.Option(
|
|
242
|
+
False, "--rerank", help="Enable reranking (Platform only).", rich_help_panel="Search"
|
|
243
|
+
),
|
|
244
|
+
keyword: bool = typer.Option(
|
|
245
|
+
False, "--keyword", help="Use keyword search.", rich_help_panel="Search"
|
|
246
|
+
),
|
|
247
|
+
filter_json: str | None = typer.Option(
|
|
248
|
+
None, "--filter", help="Advanced filter expression (JSON).", rich_help_panel="Search"
|
|
249
|
+
),
|
|
250
|
+
fields: str | None = typer.Option(
|
|
251
|
+
None,
|
|
252
|
+
"--fields",
|
|
253
|
+
help="Specific fields to return (comma-separated).",
|
|
254
|
+
rich_help_panel="Search",
|
|
255
|
+
),
|
|
256
|
+
graph: bool = typer.Option(False, "--graph", help="Enable graph in search.", rich_help_panel="Search"),
|
|
257
|
+
no_graph: bool = typer.Option(False, "--no-graph", help="Disable graph in search.", rich_help_panel="Search"),
|
|
258
|
+
output: str = typer.Option(
|
|
259
|
+
"text", "--output", "-o", help="Output: text, json, table.", rich_help_panel="Output"
|
|
260
|
+
),
|
|
261
|
+
api_key: str | None = typer.Option(
|
|
262
|
+
None,
|
|
263
|
+
"--api-key",
|
|
264
|
+
help="Override API key.",
|
|
265
|
+
envvar="MEM0_API_KEY",
|
|
266
|
+
rich_help_panel="Connection",
|
|
267
|
+
),
|
|
268
|
+
base_url: str | None = typer.Option(
|
|
269
|
+
None, "--base-url", help="Override API base URL.", rich_help_panel="Connection"
|
|
270
|
+
),
|
|
271
|
+
) -> None:
|
|
272
|
+
"""Search memories by semantic query.
|
|
273
|
+
|
|
274
|
+
Examples:
|
|
275
|
+
mem0 search "preferences" --user-id alice
|
|
276
|
+
mem0 search "tools" -u alice -o json -k 5
|
|
277
|
+
echo "preferences" | mem0 search -u alice
|
|
278
|
+
"""
|
|
279
|
+
from mem0_cli.commands.memory import cmd_search
|
|
280
|
+
|
|
281
|
+
# STEP 7: stdin fallback for query
|
|
282
|
+
if query is None:
|
|
283
|
+
query = _read_stdin()
|
|
284
|
+
if query is None:
|
|
285
|
+
print_error(err_console, "No query provided. Pass a query argument or pipe via stdin.")
|
|
286
|
+
raise typer.Exit(1)
|
|
287
|
+
|
|
288
|
+
backend, config = _get_backend_and_config(api_key, base_url)
|
|
289
|
+
ids = _resolve_ids(config, user_id=user_id, agent_id=agent_id, app_id=app_id, run_id=run_id)
|
|
290
|
+
|
|
291
|
+
if no_graph:
|
|
292
|
+
graph_enabled = False
|
|
293
|
+
elif graph:
|
|
294
|
+
graph_enabled = True
|
|
295
|
+
else:
|
|
296
|
+
graph_enabled = config.defaults.enable_graph
|
|
297
|
+
|
|
298
|
+
cmd_search(
|
|
299
|
+
backend,
|
|
300
|
+
query,
|
|
301
|
+
**ids,
|
|
302
|
+
top_k=top_k,
|
|
303
|
+
threshold=threshold,
|
|
304
|
+
rerank=rerank,
|
|
305
|
+
keyword=keyword,
|
|
306
|
+
filter_json=filter_json,
|
|
307
|
+
fields=fields,
|
|
308
|
+
enable_graph=graph_enabled,
|
|
309
|
+
output=output,
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
# ── Memory: get ───────────────────────────────────────────────────────────
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
@app.command(rich_help_panel="Memory")
|
|
317
|
+
def get(
|
|
318
|
+
memory_id: str = typer.Argument(..., help="Memory ID to retrieve."),
|
|
319
|
+
output: str = typer.Option(
|
|
320
|
+
"text", "--output", "-o", help="Output: text, json.", rich_help_panel="Output"
|
|
321
|
+
),
|
|
322
|
+
api_key: str | None = typer.Option(
|
|
323
|
+
None,
|
|
324
|
+
"--api-key",
|
|
325
|
+
help="Override API key.",
|
|
326
|
+
envvar="MEM0_API_KEY",
|
|
327
|
+
rich_help_panel="Connection",
|
|
328
|
+
),
|
|
329
|
+
base_url: str | None = typer.Option(
|
|
330
|
+
None, "--base-url", help="Override API base URL.", rich_help_panel="Connection"
|
|
331
|
+
),
|
|
332
|
+
) -> None:
|
|
333
|
+
"""Get a specific memory by ID.
|
|
334
|
+
|
|
335
|
+
Examples:
|
|
336
|
+
mem0 get abc-123-def-456
|
|
337
|
+
mem0 get abc-123-def-456 -o json
|
|
338
|
+
"""
|
|
339
|
+
from mem0_cli.commands.memory import cmd_get
|
|
340
|
+
|
|
341
|
+
backend = _get_backend(api_key, base_url)
|
|
342
|
+
cmd_get(backend, memory_id, output=output)
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
# ── Memory: list ──────────────────────────────────────────────────────────
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
@app.command(name="list", rich_help_panel="Memory")
|
|
349
|
+
def list_cmd(
|
|
350
|
+
user_id: str | None = typer.Option(
|
|
351
|
+
None, "--user-id", "-u", help="Filter by user.", rich_help_panel="Scope"
|
|
352
|
+
),
|
|
353
|
+
agent_id: str | None = typer.Option(
|
|
354
|
+
None, "--agent-id", help="Filter by agent.", rich_help_panel="Scope"
|
|
355
|
+
),
|
|
356
|
+
app_id: str | None = typer.Option(
|
|
357
|
+
None, "--app-id", help="Filter by app.", rich_help_panel="Scope"
|
|
358
|
+
),
|
|
359
|
+
run_id: str | None = typer.Option(
|
|
360
|
+
None, "--run-id", help="Filter by run.", rich_help_panel="Scope"
|
|
361
|
+
),
|
|
362
|
+
page: int = typer.Option(1, "--page", help="Page number.", rich_help_panel="Pagination"),
|
|
363
|
+
page_size: int = typer.Option(
|
|
364
|
+
100, "--page-size", help="Results per page.", rich_help_panel="Pagination"
|
|
365
|
+
),
|
|
366
|
+
category: str | None = typer.Option(
|
|
367
|
+
None, "--category", help="Filter by category.", rich_help_panel="Filters"
|
|
368
|
+
),
|
|
369
|
+
after: str | None = typer.Option(
|
|
370
|
+
None, "--after", help="Created after (YYYY-MM-DD).", rich_help_panel="Filters"
|
|
371
|
+
),
|
|
372
|
+
before: str | None = typer.Option(
|
|
373
|
+
None, "--before", help="Created before (YYYY-MM-DD).", rich_help_panel="Filters"
|
|
374
|
+
),
|
|
375
|
+
graph: bool = typer.Option(False, "--graph", help="Enable graph in listing.", rich_help_panel="Filters"),
|
|
376
|
+
no_graph: bool = typer.Option(False, "--no-graph", help="Disable graph in listing.", rich_help_panel="Filters"),
|
|
377
|
+
output: str = typer.Option(
|
|
378
|
+
"table", "--output", "-o", help="Output: text, json, table.", rich_help_panel="Output"
|
|
379
|
+
),
|
|
380
|
+
api_key: str | None = typer.Option(
|
|
381
|
+
None,
|
|
382
|
+
"--api-key",
|
|
383
|
+
help="Override API key.",
|
|
384
|
+
envvar="MEM0_API_KEY",
|
|
385
|
+
rich_help_panel="Connection",
|
|
386
|
+
),
|
|
387
|
+
base_url: str | None = typer.Option(
|
|
388
|
+
None, "--base-url", help="Override API base URL.", rich_help_panel="Connection"
|
|
389
|
+
),
|
|
390
|
+
) -> None:
|
|
391
|
+
"""List memories with optional filters.
|
|
392
|
+
|
|
393
|
+
Examples:
|
|
394
|
+
mem0 list -u alice
|
|
395
|
+
mem0 list --category prefs --after 2024-01-01 -o json
|
|
396
|
+
"""
|
|
397
|
+
from mem0_cli.commands.memory import cmd_list
|
|
398
|
+
|
|
399
|
+
backend, config = _get_backend_and_config(api_key, base_url)
|
|
400
|
+
ids = _resolve_ids(config, user_id=user_id, agent_id=agent_id, app_id=app_id, run_id=run_id)
|
|
401
|
+
|
|
402
|
+
if no_graph:
|
|
403
|
+
graph_enabled = False
|
|
404
|
+
elif graph:
|
|
405
|
+
graph_enabled = True
|
|
406
|
+
else:
|
|
407
|
+
graph_enabled = config.defaults.enable_graph
|
|
408
|
+
|
|
409
|
+
cmd_list(
|
|
410
|
+
backend,
|
|
411
|
+
**ids,
|
|
412
|
+
page=page,
|
|
413
|
+
page_size=page_size,
|
|
414
|
+
category=category,
|
|
415
|
+
after=after,
|
|
416
|
+
before=before,
|
|
417
|
+
enable_graph=graph_enabled,
|
|
418
|
+
output=output,
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
# ── Memory: update ────────────────────────────────────────────────────────
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
@app.command(rich_help_panel="Memory")
|
|
426
|
+
def update(
|
|
427
|
+
memory_id: str = typer.Argument(..., help="Memory ID to update."),
|
|
428
|
+
text: str | None = typer.Argument(None, help="New memory text."),
|
|
429
|
+
metadata: str | None = typer.Option(None, "--metadata", "-m", help="Update metadata (JSON)."),
|
|
430
|
+
output: str = typer.Option(
|
|
431
|
+
"text", "--output", "-o", help="Output: text, json, quiet.", rich_help_panel="Output"
|
|
432
|
+
),
|
|
433
|
+
api_key: str | None = typer.Option(
|
|
434
|
+
None,
|
|
435
|
+
"--api-key",
|
|
436
|
+
help="Override API key.",
|
|
437
|
+
envvar="MEM0_API_KEY",
|
|
438
|
+
rich_help_panel="Connection",
|
|
439
|
+
),
|
|
440
|
+
base_url: str | None = typer.Option(
|
|
441
|
+
None, "--base-url", help="Override API base URL.", rich_help_panel="Connection"
|
|
442
|
+
),
|
|
443
|
+
) -> None:
|
|
444
|
+
"""Update a memory's text or metadata.
|
|
445
|
+
|
|
446
|
+
Examples:
|
|
447
|
+
mem0 update abc-123-def-456 "new text"
|
|
448
|
+
mem0 update abc-123 --metadata '{{"key":"val"}}'
|
|
449
|
+
echo "new text" | mem0 update abc-123
|
|
450
|
+
"""
|
|
451
|
+
from mem0_cli.commands.memory import cmd_update
|
|
452
|
+
|
|
453
|
+
# STEP 7: stdin fallback for text
|
|
454
|
+
if text is None:
|
|
455
|
+
text = _read_stdin()
|
|
456
|
+
|
|
457
|
+
backend = _get_backend(api_key, base_url)
|
|
458
|
+
cmd_update(backend, memory_id, text, metadata=metadata, output=output)
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
# ── Memory: delete ────────────────────────────────────────────────────────
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
@app.command(rich_help_panel="Memory")
|
|
465
|
+
def delete(
|
|
466
|
+
memory_id: str | None = typer.Argument(None, help="Memory ID to delete (omit when using --all or --entity)."),
|
|
467
|
+
all_: bool = typer.Option(False, "--all", help="Delete all memories matching scope filters."),
|
|
468
|
+
entity: bool = typer.Option(False, "--entity", help="Delete the entity itself and all its memories (cascade)."),
|
|
469
|
+
project: bool = typer.Option(False, "--project", help="With --all: delete ALL memories project-wide."),
|
|
470
|
+
dry_run: bool = typer.Option(False, "--dry-run", help="Show what would be deleted without deleting."),
|
|
471
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation."),
|
|
472
|
+
user_id: str | None = typer.Option(
|
|
473
|
+
None, "--user-id", "-u", help="Scope to user.", rich_help_panel="Scope"
|
|
474
|
+
),
|
|
475
|
+
agent_id: str | None = typer.Option(
|
|
476
|
+
None, "--agent-id", help="Scope to agent.", rich_help_panel="Scope"
|
|
477
|
+
),
|
|
478
|
+
app_id: str | None = typer.Option(
|
|
479
|
+
None, "--app-id", help="Scope to app.", rich_help_panel="Scope"
|
|
480
|
+
),
|
|
481
|
+
run_id: str | None = typer.Option(
|
|
482
|
+
None, "--run-id", help="Scope to run.", rich_help_panel="Scope"
|
|
483
|
+
),
|
|
484
|
+
output: str = typer.Option(
|
|
485
|
+
"text", "--output", "-o", help="Output: text, json, quiet.", rich_help_panel="Output"
|
|
486
|
+
),
|
|
487
|
+
api_key: str | None = typer.Option(
|
|
488
|
+
None,
|
|
489
|
+
"--api-key",
|
|
490
|
+
help="Override API key.",
|
|
491
|
+
envvar="MEM0_API_KEY",
|
|
492
|
+
rich_help_panel="Connection",
|
|
493
|
+
),
|
|
494
|
+
base_url: str | None = typer.Option(
|
|
495
|
+
None, "--base-url", help="Override API base URL.", rich_help_panel="Connection"
|
|
496
|
+
),
|
|
497
|
+
) -> None:
|
|
498
|
+
"""Delete a memory, all memories, or an entity.
|
|
499
|
+
|
|
500
|
+
Examples:
|
|
501
|
+
mem0 delete abc-123-def-456
|
|
502
|
+
mem0 delete abc-123 --dry-run
|
|
503
|
+
mem0 delete --all -u alice --force
|
|
504
|
+
mem0 delete --all --project --force
|
|
505
|
+
mem0 delete --entity -u alice --force
|
|
506
|
+
"""
|
|
507
|
+
# ── Validate mutual exclusion ────────────────────────────────────
|
|
508
|
+
modes = sum([memory_id is not None, all_, entity])
|
|
509
|
+
if modes > 1:
|
|
510
|
+
print_error(
|
|
511
|
+
err_console,
|
|
512
|
+
"Only one of memory ID, --all, or --entity may be used at a time.",
|
|
513
|
+
)
|
|
514
|
+
raise typer.Exit(1)
|
|
515
|
+
if modes == 0:
|
|
516
|
+
print_error(
|
|
517
|
+
err_console,
|
|
518
|
+
"Provide a memory ID, --all, or --entity.",
|
|
519
|
+
hint="Run 'mem0 delete --help' for usage.",
|
|
520
|
+
)
|
|
521
|
+
raise typer.Exit(1)
|
|
522
|
+
|
|
523
|
+
# ── Dispatch ─────────────────────────────────────────────────────
|
|
524
|
+
if memory_id is not None:
|
|
525
|
+
from mem0_cli.commands.memory import cmd_delete
|
|
526
|
+
|
|
527
|
+
backend = _get_backend(api_key, base_url)
|
|
528
|
+
cmd_delete(backend, memory_id, dry_run=dry_run, force=force, output=output)
|
|
529
|
+
|
|
530
|
+
elif all_:
|
|
531
|
+
from mem0_cli.commands.memory import cmd_delete_all
|
|
532
|
+
|
|
533
|
+
backend, config = _get_backend_and_config(api_key, base_url)
|
|
534
|
+
ids = _resolve_ids(config, user_id=user_id, agent_id=agent_id, app_id=app_id, run_id=run_id)
|
|
535
|
+
cmd_delete_all(backend, force=force, dry_run=dry_run, all_=project, **ids, output=output)
|
|
536
|
+
|
|
537
|
+
else: # --entity
|
|
538
|
+
from mem0_cli.commands.entities import cmd_entities_delete
|
|
539
|
+
|
|
540
|
+
backend = _get_backend(api_key, base_url)
|
|
541
|
+
cmd_entities_delete(
|
|
542
|
+
backend,
|
|
543
|
+
user_id=user_id,
|
|
544
|
+
agent_id=agent_id,
|
|
545
|
+
app_id=app_id,
|
|
546
|
+
run_id=run_id,
|
|
547
|
+
force=force,
|
|
548
|
+
dry_run=dry_run,
|
|
549
|
+
output=output,
|
|
550
|
+
)
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
# ── Config subcommands ────────────────────────────────────────────────────
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
@config_app.command("show")
|
|
557
|
+
def config_show(
|
|
558
|
+
output: str = typer.Option(
|
|
559
|
+
"text", "--output", "-o", help="Output: text, json.", rich_help_panel="Output"
|
|
560
|
+
),
|
|
561
|
+
) -> None:
|
|
562
|
+
"""Display current configuration (secrets redacted).
|
|
563
|
+
|
|
564
|
+
Examples:
|
|
565
|
+
mem0 config show
|
|
566
|
+
mem0 config show -o json
|
|
567
|
+
"""
|
|
568
|
+
from mem0_cli.commands.config_cmd import cmd_config_show
|
|
569
|
+
|
|
570
|
+
cmd_config_show(output=output)
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
@config_app.command("get")
|
|
574
|
+
def config_get(
|
|
575
|
+
key: str = typer.Argument(..., help="Config key (e.g. platform.api_key)."),
|
|
576
|
+
) -> None:
|
|
577
|
+
"""Get a configuration value.
|
|
578
|
+
|
|
579
|
+
Examples:
|
|
580
|
+
mem0 config get platform.api_key
|
|
581
|
+
mem0 config get defaults.user_id
|
|
582
|
+
"""
|
|
583
|
+
from mem0_cli.commands.config_cmd import cmd_config_get
|
|
584
|
+
|
|
585
|
+
cmd_config_get(key)
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
@config_app.command("set")
|
|
589
|
+
def config_set(
|
|
590
|
+
key: str = typer.Argument(..., help="Config key (e.g. platform.api_key)."),
|
|
591
|
+
value: str = typer.Argument(..., help="Value to set."),
|
|
592
|
+
) -> None:
|
|
593
|
+
"""Set a configuration value.
|
|
594
|
+
|
|
595
|
+
Examples:
|
|
596
|
+
mem0 config set defaults.user_id alice
|
|
597
|
+
mem0 config set platform.base_url https://custom.api.mem0.ai
|
|
598
|
+
"""
|
|
599
|
+
from mem0_cli.commands.config_cmd import cmd_config_set
|
|
600
|
+
|
|
601
|
+
cmd_config_set(key, value)
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
# ── Entity subcommands ────────────────────────────────────────────────────
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
@entity_app.command("list")
|
|
608
|
+
def entity_list(
|
|
609
|
+
entity_type: str = typer.Argument(..., help="Entity type: users, agents, apps, runs."),
|
|
610
|
+
output: str = typer.Option(
|
|
611
|
+
"table", "--output", "-o", help="Output: table, json.", rich_help_panel="Output"
|
|
612
|
+
),
|
|
613
|
+
api_key: str | None = typer.Option(
|
|
614
|
+
None,
|
|
615
|
+
"--api-key",
|
|
616
|
+
help="Override API key.",
|
|
617
|
+
envvar="MEM0_API_KEY",
|
|
618
|
+
rich_help_panel="Connection",
|
|
619
|
+
),
|
|
620
|
+
base_url: str | None = typer.Option(
|
|
621
|
+
None, "--base-url", help="Override API base URL.", rich_help_panel="Connection"
|
|
622
|
+
),
|
|
623
|
+
) -> None:
|
|
624
|
+
"""List all entities of a given type.
|
|
625
|
+
|
|
626
|
+
Examples:
|
|
627
|
+
mem0 entity list users
|
|
628
|
+
mem0 entity list agents -o json
|
|
629
|
+
"""
|
|
630
|
+
from mem0_cli.commands.entities import cmd_entities_list
|
|
631
|
+
|
|
632
|
+
backend = _get_backend(api_key, base_url)
|
|
633
|
+
cmd_entities_list(backend, entity_type, output=output)
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
@entity_app.command("delete")
|
|
637
|
+
def entity_delete(
|
|
638
|
+
user_id: str | None = typer.Option(
|
|
639
|
+
None, "--user-id", "-u", help="User ID.", rich_help_panel="Scope"
|
|
640
|
+
),
|
|
641
|
+
agent_id: str | None = typer.Option(
|
|
642
|
+
None, "--agent-id", help="Agent ID.", rich_help_panel="Scope"
|
|
643
|
+
),
|
|
644
|
+
app_id: str | None = typer.Option(
|
|
645
|
+
None, "--app-id", help="App ID.", rich_help_panel="Scope"
|
|
646
|
+
),
|
|
647
|
+
run_id: str | None = typer.Option(
|
|
648
|
+
None, "--run-id", help="Run ID.", rich_help_panel="Scope"
|
|
649
|
+
),
|
|
650
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation."),
|
|
651
|
+
dry_run: bool = typer.Option(False, "--dry-run", help="Show what would be deleted without deleting."),
|
|
652
|
+
output: str = typer.Option(
|
|
653
|
+
"text", "--output", "-o", help="Output: text, json, quiet.", rich_help_panel="Output"
|
|
654
|
+
),
|
|
655
|
+
api_key: str | None = typer.Option(
|
|
656
|
+
None,
|
|
657
|
+
"--api-key",
|
|
658
|
+
help="Override API key.",
|
|
659
|
+
envvar="MEM0_API_KEY",
|
|
660
|
+
rich_help_panel="Connection",
|
|
661
|
+
),
|
|
662
|
+
base_url: str | None = typer.Option(
|
|
663
|
+
None, "--base-url", help="Override API base URL.", rich_help_panel="Connection"
|
|
664
|
+
),
|
|
665
|
+
) -> None:
|
|
666
|
+
"""Delete an entity and ALL its memories (cascade).
|
|
667
|
+
|
|
668
|
+
Examples:
|
|
669
|
+
mem0 entity delete --user-id alice --force
|
|
670
|
+
mem0 entity delete -u alice --dry-run
|
|
671
|
+
"""
|
|
672
|
+
from mem0_cli.commands.entities import cmd_entities_delete
|
|
673
|
+
|
|
674
|
+
backend = _get_backend(api_key, base_url)
|
|
675
|
+
cmd_entities_delete(
|
|
676
|
+
backend,
|
|
677
|
+
user_id=user_id,
|
|
678
|
+
agent_id=agent_id,
|
|
679
|
+
app_id=app_id,
|
|
680
|
+
run_id=run_id,
|
|
681
|
+
force=force,
|
|
682
|
+
dry_run=dry_run,
|
|
683
|
+
output=output,
|
|
684
|
+
)
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
# ── Entity subgroup ──
|
|
688
|
+
app.add_typer(entity_app, name="entity", rich_help_panel="Management")
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
# ── Management commands ───────────────────────────────────────────────────
|
|
692
|
+
|
|
693
|
+
|
|
694
|
+
@app.command(rich_help_panel="Management")
|
|
695
|
+
def init(
|
|
696
|
+
api_key: str | None = typer.Option(None, "--api-key", help="API key (skip prompt)."),
|
|
697
|
+
user_id: str | None = typer.Option(None, "--user-id", "-u", help="Default user ID (skip prompt)."),
|
|
698
|
+
) -> None:
|
|
699
|
+
"""Interactive setup wizard for mem0 CLI.
|
|
700
|
+
|
|
701
|
+
Examples:
|
|
702
|
+
mem0 init
|
|
703
|
+
mem0 init --api-key m0-xxx --user-id alice
|
|
704
|
+
"""
|
|
705
|
+
from mem0_cli.commands.init_cmd import run_init
|
|
706
|
+
|
|
707
|
+
run_init(api_key=api_key, user_id=user_id)
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
# (entity_app registered at module level, below sub-group definitions)
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
@app.command(rich_help_panel="Management")
|
|
714
|
+
def status(
|
|
715
|
+
output: str = typer.Option(
|
|
716
|
+
"text", "--output", "-o", help="Output: text, json.", rich_help_panel="Output"
|
|
717
|
+
),
|
|
718
|
+
api_key: str | None = typer.Option(
|
|
719
|
+
None,
|
|
720
|
+
"--api-key",
|
|
721
|
+
help="Override API key.",
|
|
722
|
+
envvar="MEM0_API_KEY",
|
|
723
|
+
rich_help_panel="Connection",
|
|
724
|
+
),
|
|
725
|
+
base_url: str | None = typer.Option(
|
|
726
|
+
None, "--base-url", help="Override API base URL.", rich_help_panel="Connection"
|
|
727
|
+
),
|
|
728
|
+
) -> None:
|
|
729
|
+
"""Check connectivity and authentication.
|
|
730
|
+
|
|
731
|
+
Examples:
|
|
732
|
+
mem0 status
|
|
733
|
+
mem0 status -o json
|
|
734
|
+
"""
|
|
735
|
+
from mem0_cli.commands.utils import cmd_status
|
|
736
|
+
|
|
737
|
+
backend, config = _get_backend_and_config(api_key, base_url)
|
|
738
|
+
cmd_status(
|
|
739
|
+
backend,
|
|
740
|
+
user_id=config.defaults.user_id or None,
|
|
741
|
+
agent_id=config.defaults.agent_id or None,
|
|
742
|
+
output=output,
|
|
743
|
+
)
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
@app.command("import", rich_help_panel="Management")
|
|
748
|
+
def import_cmd(
|
|
749
|
+
file_path: str = typer.Argument(..., help="JSON file to import."),
|
|
750
|
+
user_id: str | None = typer.Option(
|
|
751
|
+
None, "--user-id", "-u", help="Override user ID.", rich_help_panel="Scope"
|
|
752
|
+
),
|
|
753
|
+
agent_id: str | None = typer.Option(
|
|
754
|
+
None, "--agent-id", help="Override agent ID.", rich_help_panel="Scope"
|
|
755
|
+
),
|
|
756
|
+
output: str = typer.Option(
|
|
757
|
+
"text", "--output", "-o", help="Output: text, json.", rich_help_panel="Output"
|
|
758
|
+
),
|
|
759
|
+
api_key: str | None = typer.Option(
|
|
760
|
+
None,
|
|
761
|
+
"--api-key",
|
|
762
|
+
help="Override API key.",
|
|
763
|
+
envvar="MEM0_API_KEY",
|
|
764
|
+
rich_help_panel="Connection",
|
|
765
|
+
),
|
|
766
|
+
base_url: str | None = typer.Option(
|
|
767
|
+
None, "--base-url", help="Override API base URL.", rich_help_panel="Connection"
|
|
768
|
+
),
|
|
769
|
+
) -> None:
|
|
770
|
+
"""Import memories from a JSON file.
|
|
771
|
+
|
|
772
|
+
Examples:
|
|
773
|
+
mem0 import data.json --user-id alice
|
|
774
|
+
mem0 import data.json -u alice -o json
|
|
775
|
+
"""
|
|
776
|
+
from mem0_cli.commands.utils import cmd_import
|
|
777
|
+
|
|
778
|
+
backend, config = _get_backend_and_config(api_key, base_url)
|
|
779
|
+
ids = _resolve_ids(config, user_id=user_id, agent_id=agent_id)
|
|
780
|
+
cmd_import(backend, file_path, user_id=ids["user_id"], agent_id=ids["agent_id"], output=output)
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
# ── Help (machine-readable) ──────────────────────────────────────────────
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
def _build_help_json() -> dict:
|
|
787
|
+
"""Build machine-readable JSON describing all CLI commands."""
|
|
788
|
+
commands = {
|
|
789
|
+
"add": {
|
|
790
|
+
"description": "Add a memory from text, messages, file, or stdin.",
|
|
791
|
+
"usage": "mem0 add <text> [OPTIONS]",
|
|
792
|
+
"arguments": {
|
|
793
|
+
"text": {"description": "Text content to add as a memory.", "required": False}
|
|
794
|
+
},
|
|
795
|
+
"options": {
|
|
796
|
+
"--user-id, -u": "Scope to user.",
|
|
797
|
+
"--agent-id": "Scope to agent.",
|
|
798
|
+
"--app-id": "Scope to app.",
|
|
799
|
+
"--run-id": "Scope to run.",
|
|
800
|
+
"--messages": "Conversation messages as JSON.",
|
|
801
|
+
"--file, -f": "Read messages from JSON file.",
|
|
802
|
+
"--metadata, -m": "Custom metadata as JSON.",
|
|
803
|
+
"--immutable": "Prevent future updates.",
|
|
804
|
+
"--no-infer": "Skip inference, store raw.",
|
|
805
|
+
"--expires": "Expiration date (YYYY-MM-DD).",
|
|
806
|
+
"--categories": "Categories (JSON array or comma-separated).",
|
|
807
|
+
"--graph": "Enable graph memory extraction.",
|
|
808
|
+
"--no-graph": "Disable graph memory extraction.",
|
|
809
|
+
"--output, -o": "Output format: text, json, quiet.",
|
|
810
|
+
},
|
|
811
|
+
},
|
|
812
|
+
"search": {
|
|
813
|
+
"description": "Search memories by semantic query.",
|
|
814
|
+
"usage": "mem0 search <query> [OPTIONS]",
|
|
815
|
+
"arguments": {"query": {"description": "Search query.", "required": False}},
|
|
816
|
+
"options": {
|
|
817
|
+
"--user-id, -u": "Filter by user.",
|
|
818
|
+
"--agent-id": "Filter by agent.",
|
|
819
|
+
"--top-k, -k, --limit": "Number of results (default: 10).",
|
|
820
|
+
"--threshold": "Minimum similarity score (default: 0.3).",
|
|
821
|
+
"--rerank": "Enable reranking (Platform only).",
|
|
822
|
+
"--keyword": "Use keyword search instead of semantic.",
|
|
823
|
+
"--filter": "Advanced filter expression (JSON).",
|
|
824
|
+
"--fields": "Specific fields to return (comma-separated).",
|
|
825
|
+
"--graph": "Enable graph in search.",
|
|
826
|
+
"--no-graph": "Disable graph in search.",
|
|
827
|
+
"--output, -o": "Output format: text, json, table.",
|
|
828
|
+
},
|
|
829
|
+
},
|
|
830
|
+
"get": {
|
|
831
|
+
"description": "Get a specific memory by ID.",
|
|
832
|
+
"usage": "mem0 get <memory_id> [OPTIONS]",
|
|
833
|
+
"arguments": {"memory_id": {"description": "Memory ID to retrieve.", "required": True}},
|
|
834
|
+
"options": {"--output, -o": "Output format: text, json."},
|
|
835
|
+
},
|
|
836
|
+
"list": {
|
|
837
|
+
"description": "List memories with optional filters.",
|
|
838
|
+
"usage": "mem0 list [OPTIONS]",
|
|
839
|
+
"arguments": {},
|
|
840
|
+
"options": {
|
|
841
|
+
"--user-id, -u": "Filter by user.",
|
|
842
|
+
"--agent-id": "Filter by agent.",
|
|
843
|
+
"--page": "Page number (default: 1).",
|
|
844
|
+
"--page-size": "Results per page (default: 100).",
|
|
845
|
+
"--category": "Filter by category.",
|
|
846
|
+
"--after": "Created after (YYYY-MM-DD).",
|
|
847
|
+
"--before": "Created before (YYYY-MM-DD).",
|
|
848
|
+
"--graph": "Enable graph in listing.",
|
|
849
|
+
"--no-graph": "Disable graph in listing.",
|
|
850
|
+
"--output, -o": "Output format: text, json, table.",
|
|
851
|
+
},
|
|
852
|
+
},
|
|
853
|
+
"update": {
|
|
854
|
+
"description": "Update a memory's text or metadata.",
|
|
855
|
+
"usage": "mem0 update <memory_id> [text] [OPTIONS]",
|
|
856
|
+
"arguments": {
|
|
857
|
+
"memory_id": {"description": "Memory ID to update.", "required": True},
|
|
858
|
+
"text": {"description": "New memory text.", "required": False},
|
|
859
|
+
},
|
|
860
|
+
"options": {
|
|
861
|
+
"--metadata, -m": "Update metadata (JSON).",
|
|
862
|
+
"--output, -o": "Output format: text, json, quiet.",
|
|
863
|
+
},
|
|
864
|
+
},
|
|
865
|
+
"delete": {
|
|
866
|
+
"description": "Delete a memory, all memories, or an entity.",
|
|
867
|
+
"usage": "mem0 delete [memory_id] [OPTIONS]",
|
|
868
|
+
"arguments": {
|
|
869
|
+
"memory_id": {
|
|
870
|
+
"description": "Memory ID to delete (omit when using --all or --entity).",
|
|
871
|
+
"required": False,
|
|
872
|
+
}
|
|
873
|
+
},
|
|
874
|
+
"options": {
|
|
875
|
+
"--all": "Delete all memories matching scope filters.",
|
|
876
|
+
"--entity": "Delete the entity itself and all its memories (cascade).",
|
|
877
|
+
"--project": "With --all: delete ALL memories project-wide.",
|
|
878
|
+
"--dry-run": "Show what would be deleted without deleting.",
|
|
879
|
+
"--force": "Skip confirmation.",
|
|
880
|
+
"--user-id, -u": "Scope to user.",
|
|
881
|
+
"--agent-id": "Scope to agent.",
|
|
882
|
+
"--app-id": "Scope to app.",
|
|
883
|
+
"--run-id": "Scope to run.",
|
|
884
|
+
"--output, -o": "Output format: text, json, quiet.",
|
|
885
|
+
},
|
|
886
|
+
},
|
|
887
|
+
"import": {
|
|
888
|
+
"description": "Import memories from a JSON file.",
|
|
889
|
+
"usage": "mem0 import <file_path> [OPTIONS]",
|
|
890
|
+
"arguments": {"file_path": {"description": "JSON file to import.", "required": True}},
|
|
891
|
+
"options": {
|
|
892
|
+
"--user-id, -u": "Override user ID.",
|
|
893
|
+
"--agent-id": "Override agent ID.",
|
|
894
|
+
"--output, -o": "Output format: text, json.",
|
|
895
|
+
},
|
|
896
|
+
},
|
|
897
|
+
"config show": {
|
|
898
|
+
"description": "Display current configuration (secrets redacted).",
|
|
899
|
+
"usage": "mem0 config show",
|
|
900
|
+
"options": {"--output, -o": "Output format: text, json."},
|
|
901
|
+
},
|
|
902
|
+
"config get": {
|
|
903
|
+
"description": "Get a configuration value.",
|
|
904
|
+
"usage": "mem0 config get <key>",
|
|
905
|
+
"arguments": {
|
|
906
|
+
"key": {"description": "Config key (e.g. platform.api_key).", "required": True}
|
|
907
|
+
},
|
|
908
|
+
},
|
|
909
|
+
"config set": {
|
|
910
|
+
"description": "Set a configuration value.",
|
|
911
|
+
"usage": "mem0 config set <key> <value>",
|
|
912
|
+
"arguments": {
|
|
913
|
+
"key": {"description": "Config key (e.g. platform.api_key).", "required": True},
|
|
914
|
+
"value": {"description": "Value to set.", "required": True},
|
|
915
|
+
},
|
|
916
|
+
},
|
|
917
|
+
"entity": {
|
|
918
|
+
"description": "Manage entities.",
|
|
919
|
+
"subcommands": {
|
|
920
|
+
"list": {
|
|
921
|
+
"description": "List all entities of a given type.",
|
|
922
|
+
"usage": "mem0 entity list <entity_type> [OPTIONS]",
|
|
923
|
+
"arguments": {
|
|
924
|
+
"entity_type": {
|
|
925
|
+
"description": "Entity type: users, agents, apps, runs.",
|
|
926
|
+
"required": True,
|
|
927
|
+
}
|
|
928
|
+
},
|
|
929
|
+
"options": {"--output, -o": "Output format: table, json."},
|
|
930
|
+
},
|
|
931
|
+
"delete": {
|
|
932
|
+
"description": "Delete an entity and ALL its memories (cascade).",
|
|
933
|
+
"usage": "mem0 entity delete [OPTIONS]",
|
|
934
|
+
"options": {
|
|
935
|
+
"--user-id, -u": "User ID.",
|
|
936
|
+
"--agent-id": "Agent ID.",
|
|
937
|
+
"--app-id": "App ID.",
|
|
938
|
+
"--run-id": "Run ID.",
|
|
939
|
+
"--force": "Skip confirmation.",
|
|
940
|
+
"--dry-run": "Show what would be deleted without deleting.",
|
|
941
|
+
"--output, -o": "Output format: text, json, quiet.",
|
|
942
|
+
},
|
|
943
|
+
},
|
|
944
|
+
},
|
|
945
|
+
},
|
|
946
|
+
"init": {
|
|
947
|
+
"description": "Interactive setup wizard for mem0 CLI.",
|
|
948
|
+
"usage": "mem0 init",
|
|
949
|
+
"options": {
|
|
950
|
+
"--api-key": "API key (skip prompt).",
|
|
951
|
+
"--user-id, -u": "Default user ID (skip prompt).",
|
|
952
|
+
},
|
|
953
|
+
},
|
|
954
|
+
"status": {
|
|
955
|
+
"description": "Check connectivity and authentication.",
|
|
956
|
+
"usage": "mem0 status [OPTIONS]",
|
|
957
|
+
"options": {"--output, -o": "Output format: text, json."},
|
|
958
|
+
},
|
|
959
|
+
}
|
|
960
|
+
return {
|
|
961
|
+
"name": "mem0",
|
|
962
|
+
"version": __version__,
|
|
963
|
+
"description": "The Memory Layer for AI Agents",
|
|
964
|
+
"commands": commands,
|
|
965
|
+
"global_options": {
|
|
966
|
+
"--api-key": "Override API key (env: MEM0_API_KEY).",
|
|
967
|
+
"--base-url": "Override API base URL.",
|
|
968
|
+
"--help": "Show help for a command.",
|
|
969
|
+
"--version": "Show version and exit.",
|
|
970
|
+
},
|
|
971
|
+
"help": {
|
|
972
|
+
"human": "mem0 <command> --help Get help for a command",
|
|
973
|
+
"machine": "mem0 help --json Machine-readable help (for LLM agents)",
|
|
974
|
+
},
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
|
|
978
|
+
@app.command(rich_help_panel="Management")
|
|
979
|
+
def help(
|
|
980
|
+
json: bool = typer.Option(False, "--json", help="Output machine-readable JSON for LLM agents."),
|
|
981
|
+
) -> None:
|
|
982
|
+
"""Show help. Use --json for machine-readable output (for LLM agents).
|
|
983
|
+
|
|
984
|
+
Examples:
|
|
985
|
+
mem0 help
|
|
986
|
+
mem0 help --json
|
|
987
|
+
"""
|
|
988
|
+
if json:
|
|
989
|
+
console.print(_json.dumps(_build_help_json(), indent=2))
|
|
990
|
+
else:
|
|
991
|
+
console.print(
|
|
992
|
+
f"[{BRAND_COLOR}]◆ mem0 CLI[/] v{__version__} — The Memory Layer for AI Agents\n"
|
|
993
|
+
)
|
|
994
|
+
console.print("Usage: mem0 <command> [OPTIONS]\n")
|
|
995
|
+
console.print("[bold]Commands:[/]")
|
|
996
|
+
console.print(" add Add a memory from text, messages, file, or stdin")
|
|
997
|
+
console.print(" search Search memories by semantic query")
|
|
998
|
+
console.print(" get Get a specific memory by ID")
|
|
999
|
+
console.print(" list List memories with optional filters")
|
|
1000
|
+
console.print(" update Update a memory's text or metadata")
|
|
1001
|
+
console.print(" delete Delete a memory, all memories, or an entity")
|
|
1002
|
+
console.print(" import Import memories from a JSON file")
|
|
1003
|
+
console.print(" config Manage configuration (show, get, set)")
|
|
1004
|
+
console.print(" entity Manage entities (list, delete)")
|
|
1005
|
+
console.print(" init Interactive setup wizard")
|
|
1006
|
+
console.print(" status Check connectivity and authentication")
|
|
1007
|
+
console.print()
|
|
1008
|
+
console.print(" mem0 <command> --help Get help for a command")
|
|
1009
|
+
console.print(" mem0 help --json Machine-readable help (for LLM agents)")
|
|
1010
|
+
console.print()
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
# Register config subgroup here so it appears after help in Management panel
|
|
1014
|
+
app.add_typer(config_app, name="config", rich_help_panel="Management")
|
|
1015
|
+
|
|
1016
|
+
|
|
1017
|
+
# ── Entrypoint ────────────────────────────────────────────────────────────
|
|
1018
|
+
|
|
1019
|
+
|
|
1020
|
+
def main() -> None:
|
|
1021
|
+
app()
|