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/config.py
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"""Configuration management for mem0 CLI.
|
|
2
|
+
|
|
3
|
+
Config precedence (highest to lowest):
|
|
4
|
+
1. CLI flags (--api-key, --base-url, etc.)
|
|
5
|
+
2. Environment variables (MEM0_API_KEY, etc.)
|
|
6
|
+
3. Config file (~/.mem0/config.json)
|
|
7
|
+
4. Defaults
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
import os
|
|
14
|
+
import stat
|
|
15
|
+
from dataclasses import dataclass, field
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
19
|
+
CONFIG_DIR = Path.home() / ".mem0"
|
|
20
|
+
CONFIG_FILE = CONFIG_DIR / "config.json"
|
|
21
|
+
|
|
22
|
+
DEFAULT_BASE_URL = "https://api.mem0.ai"
|
|
23
|
+
CONFIG_VERSION = 1
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class PlatformConfig:
|
|
28
|
+
api_key: str = ""
|
|
29
|
+
base_url: str = DEFAULT_BASE_URL
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class DefaultsConfig:
|
|
34
|
+
user_id: str = ""
|
|
35
|
+
agent_id: str = ""
|
|
36
|
+
app_id: str = ""
|
|
37
|
+
run_id: str = ""
|
|
38
|
+
enable_graph: bool = False
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class Mem0Config:
|
|
43
|
+
version: int = CONFIG_VERSION
|
|
44
|
+
defaults: DefaultsConfig = field(default_factory=DefaultsConfig)
|
|
45
|
+
platform: PlatformConfig = field(default_factory=PlatformConfig)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def ensure_config_dir() -> Path:
|
|
49
|
+
"""Create ~/.mem0 directory with secure permissions if it doesn't exist."""
|
|
50
|
+
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
|
51
|
+
os.chmod(CONFIG_DIR, stat.S_IRWXU) # 0700
|
|
52
|
+
return CONFIG_DIR
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def load_config() -> Mem0Config:
|
|
56
|
+
"""Load config from file, applying env var overrides."""
|
|
57
|
+
config = Mem0Config()
|
|
58
|
+
|
|
59
|
+
if CONFIG_FILE.exists():
|
|
60
|
+
with open(CONFIG_FILE) as f:
|
|
61
|
+
data = json.load(f)
|
|
62
|
+
|
|
63
|
+
config.version = data.get("version", CONFIG_VERSION)
|
|
64
|
+
|
|
65
|
+
plat = data.get("platform", {})
|
|
66
|
+
config.platform.api_key = plat.get("api_key", "")
|
|
67
|
+
config.platform.base_url = plat.get("base_url", DEFAULT_BASE_URL)
|
|
68
|
+
|
|
69
|
+
defaults = data.get("defaults", {})
|
|
70
|
+
config.defaults.user_id = defaults.get("user_id", "")
|
|
71
|
+
config.defaults.agent_id = defaults.get("agent_id", "")
|
|
72
|
+
config.defaults.app_id = defaults.get("app_id", "")
|
|
73
|
+
config.defaults.run_id = defaults.get("run_id", "")
|
|
74
|
+
config.defaults.enable_graph = defaults.get("enable_graph", False)
|
|
75
|
+
|
|
76
|
+
# Environment variable overrides
|
|
77
|
+
env_key = os.environ.get("MEM0_API_KEY")
|
|
78
|
+
if env_key:
|
|
79
|
+
config.platform.api_key = env_key
|
|
80
|
+
|
|
81
|
+
env_base = os.environ.get("MEM0_BASE_URL")
|
|
82
|
+
if env_base:
|
|
83
|
+
config.platform.base_url = env_base
|
|
84
|
+
|
|
85
|
+
env_user_id = os.environ.get("MEM0_USER_ID")
|
|
86
|
+
if env_user_id:
|
|
87
|
+
config.defaults.user_id = env_user_id
|
|
88
|
+
|
|
89
|
+
env_agent_id = os.environ.get("MEM0_AGENT_ID")
|
|
90
|
+
if env_agent_id:
|
|
91
|
+
config.defaults.agent_id = env_agent_id
|
|
92
|
+
|
|
93
|
+
env_app_id = os.environ.get("MEM0_APP_ID")
|
|
94
|
+
if env_app_id:
|
|
95
|
+
config.defaults.app_id = env_app_id
|
|
96
|
+
|
|
97
|
+
env_run_id = os.environ.get("MEM0_RUN_ID")
|
|
98
|
+
if env_run_id:
|
|
99
|
+
config.defaults.run_id = env_run_id
|
|
100
|
+
|
|
101
|
+
env_graph = os.environ.get("MEM0_ENABLE_GRAPH")
|
|
102
|
+
if env_graph:
|
|
103
|
+
config.defaults.enable_graph = env_graph.lower() in ("true", "1", "yes")
|
|
104
|
+
|
|
105
|
+
return config
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def save_config(config: Mem0Config) -> None:
|
|
109
|
+
"""Write config to disk with secure permissions."""
|
|
110
|
+
ensure_config_dir()
|
|
111
|
+
|
|
112
|
+
data: dict[str, Any] = {
|
|
113
|
+
"version": config.version,
|
|
114
|
+
"defaults": {
|
|
115
|
+
"user_id": config.defaults.user_id,
|
|
116
|
+
"agent_id": config.defaults.agent_id,
|
|
117
|
+
"app_id": config.defaults.app_id,
|
|
118
|
+
"run_id": config.defaults.run_id,
|
|
119
|
+
"enable_graph": config.defaults.enable_graph,
|
|
120
|
+
},
|
|
121
|
+
"platform": {
|
|
122
|
+
"api_key": config.platform.api_key,
|
|
123
|
+
"base_url": config.platform.base_url,
|
|
124
|
+
},
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
with open(CONFIG_FILE, "w") as f:
|
|
128
|
+
json.dump(data, f, indent=2)
|
|
129
|
+
|
|
130
|
+
os.chmod(CONFIG_FILE, stat.S_IRUSR | stat.S_IWUSR) # 0600
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def redact_key(key: str) -> str:
|
|
134
|
+
"""Redact an API key for display: m0-xxx...xxx"""
|
|
135
|
+
if not key:
|
|
136
|
+
return "(not set)"
|
|
137
|
+
if len(key) <= 8:
|
|
138
|
+
return key[:2] + "***"
|
|
139
|
+
return key[:4] + "..." + key[-4:]
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def get_nested_value(config: Mem0Config, dotted_key: str) -> Any:
|
|
143
|
+
"""Get a config value by dotted path, e.g. 'platform.api_key'."""
|
|
144
|
+
parts = dotted_key.split(".")
|
|
145
|
+
obj: Any = config
|
|
146
|
+
for part in parts:
|
|
147
|
+
if hasattr(obj, part):
|
|
148
|
+
obj = getattr(obj, part)
|
|
149
|
+
else:
|
|
150
|
+
return None
|
|
151
|
+
return obj
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def set_nested_value(config: Mem0Config, dotted_key: str, value: str) -> bool:
|
|
155
|
+
"""Set a config value by dotted path. Returns True on success."""
|
|
156
|
+
parts = dotted_key.split(".")
|
|
157
|
+
obj: Any = config
|
|
158
|
+
for part in parts[:-1]:
|
|
159
|
+
if hasattr(obj, part):
|
|
160
|
+
obj = getattr(obj, part)
|
|
161
|
+
else:
|
|
162
|
+
return False
|
|
163
|
+
|
|
164
|
+
final_key = parts[-1]
|
|
165
|
+
if not hasattr(obj, final_key):
|
|
166
|
+
return False
|
|
167
|
+
|
|
168
|
+
current = getattr(obj, final_key)
|
|
169
|
+
# Type coercion
|
|
170
|
+
if isinstance(current, bool):
|
|
171
|
+
value = value.lower() in ("true", "1", "yes") # type: ignore[assignment]
|
|
172
|
+
elif isinstance(current, int):
|
|
173
|
+
value = int(value) # type: ignore[assignment]
|
|
174
|
+
|
|
175
|
+
setattr(obj, final_key, value)
|
|
176
|
+
return True
|
mem0_cli/output.py
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"""Output formatting for mem0 CLI — text, JSON, table, quiet modes."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from rich.panel import Panel
|
|
11
|
+
from rich.table import Table
|
|
12
|
+
from rich.text import Text
|
|
13
|
+
|
|
14
|
+
from mem0_cli.branding import ACCENT_COLOR, BRAND_COLOR, DIM_COLOR, SUCCESS_COLOR, _sym
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def format_memories_text(console: Console, memories: list[dict], title: str = "memories") -> None:
|
|
18
|
+
"""Render memories in human-friendly text mode."""
|
|
19
|
+
count = len(memories)
|
|
20
|
+
console.print(f"\n[{BRAND_COLOR}]Found {count} {title}:[/]\n")
|
|
21
|
+
|
|
22
|
+
for i, mem in enumerate(memories, 1):
|
|
23
|
+
memory_text = mem.get("memory", mem.get("text", ""))
|
|
24
|
+
mem_id = mem.get("id", "")[:8]
|
|
25
|
+
score = mem.get("score")
|
|
26
|
+
created = _format_date(mem.get("created_at"))
|
|
27
|
+
category = mem.get("categories", [None])
|
|
28
|
+
if isinstance(category, list):
|
|
29
|
+
category = category[0] if category else None
|
|
30
|
+
|
|
31
|
+
line = Text()
|
|
32
|
+
line.append(f" {i}. ", style="bold")
|
|
33
|
+
line.append(memory_text, style="white")
|
|
34
|
+
console.print(line)
|
|
35
|
+
|
|
36
|
+
details = []
|
|
37
|
+
if score is not None:
|
|
38
|
+
details.append(f"Score: {score:.2f}")
|
|
39
|
+
if mem_id:
|
|
40
|
+
details.append(f"ID: {mem_id}")
|
|
41
|
+
if created:
|
|
42
|
+
details.append(f"Created: {created}")
|
|
43
|
+
if category:
|
|
44
|
+
details.append(f"Category: {category}")
|
|
45
|
+
|
|
46
|
+
if details:
|
|
47
|
+
detail_str = " · ".join(details)
|
|
48
|
+
console.print(f" [{DIM_COLOR}]{detail_str}[/]")
|
|
49
|
+
console.print()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def format_memories_table(console: Console, memories: list[dict]) -> None:
|
|
53
|
+
"""Render memories in a rich table."""
|
|
54
|
+
table = Table(
|
|
55
|
+
border_style=BRAND_COLOR,
|
|
56
|
+
header_style=f"bold {ACCENT_COLOR}",
|
|
57
|
+
row_styles=["", "dim"],
|
|
58
|
+
padding=(0, 1),
|
|
59
|
+
)
|
|
60
|
+
table.add_column("ID", style="dim", max_width=10)
|
|
61
|
+
table.add_column("Memory", max_width=50, no_wrap=False)
|
|
62
|
+
table.add_column("Category", max_width=14)
|
|
63
|
+
table.add_column("Created", max_width=12)
|
|
64
|
+
|
|
65
|
+
for mem in memories:
|
|
66
|
+
mem_id = mem.get("id", "")[:8]
|
|
67
|
+
memory_text = mem.get("memory", mem.get("text", ""))
|
|
68
|
+
if len(memory_text) > 60:
|
|
69
|
+
memory_text = memory_text[:57] + "..."
|
|
70
|
+
categories = mem.get("categories", [])
|
|
71
|
+
cat = categories[0] if isinstance(categories, list) and categories else "—"
|
|
72
|
+
created = _format_date(mem.get("created_at")) or "—"
|
|
73
|
+
table.add_row(mem_id, memory_text, cat, created)
|
|
74
|
+
|
|
75
|
+
console.print()
|
|
76
|
+
console.print(table)
|
|
77
|
+
console.print()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def format_json(console: Console, data: Any) -> None:
|
|
81
|
+
"""Output data as pretty-printed JSON."""
|
|
82
|
+
console.print_json(json.dumps(data, default=str))
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def format_single_memory(console: Console, mem: dict, output: str = "text") -> None:
|
|
86
|
+
"""Format a single memory for display."""
|
|
87
|
+
if output == "json":
|
|
88
|
+
format_json(console, mem)
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
memory_text = mem.get("memory", mem.get("text", ""))
|
|
92
|
+
mem_id = mem.get("id", "")
|
|
93
|
+
|
|
94
|
+
lines = []
|
|
95
|
+
lines.append(f" [white bold]{memory_text}[/]")
|
|
96
|
+
lines.append("")
|
|
97
|
+
|
|
98
|
+
if mem_id:
|
|
99
|
+
lines.append(f" [{DIM_COLOR}]ID:[/] {mem_id}")
|
|
100
|
+
created = _format_date(mem.get("created_at"))
|
|
101
|
+
if created:
|
|
102
|
+
lines.append(f" [{DIM_COLOR}]Created:[/] {created}")
|
|
103
|
+
updated = _format_date(mem.get("updated_at"))
|
|
104
|
+
if updated:
|
|
105
|
+
lines.append(f" [{DIM_COLOR}]Updated:[/] {updated}")
|
|
106
|
+
meta = mem.get("metadata")
|
|
107
|
+
if meta:
|
|
108
|
+
lines.append(f" [{DIM_COLOR}]Metadata:[/] {json.dumps(meta)}")
|
|
109
|
+
categories = mem.get("categories")
|
|
110
|
+
if categories:
|
|
111
|
+
cat_str = ", ".join(categories) if isinstance(categories, list) else categories
|
|
112
|
+
lines.append(f" [{DIM_COLOR}]Categories:[/] {cat_str}")
|
|
113
|
+
|
|
114
|
+
content = "\n".join(lines)
|
|
115
|
+
panel = Panel(
|
|
116
|
+
content,
|
|
117
|
+
title=f"[{BRAND_COLOR}]Memory[/]",
|
|
118
|
+
title_align="left",
|
|
119
|
+
border_style=BRAND_COLOR,
|
|
120
|
+
padding=(1, 1),
|
|
121
|
+
)
|
|
122
|
+
console.print()
|
|
123
|
+
console.print(panel)
|
|
124
|
+
console.print()
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def format_add_result(console: Console, result: dict | list, output: str = "text") -> None:
|
|
128
|
+
"""Format the result of an add operation."""
|
|
129
|
+
if output == "json":
|
|
130
|
+
format_json(console, result)
|
|
131
|
+
return
|
|
132
|
+
if output == "quiet":
|
|
133
|
+
return
|
|
134
|
+
|
|
135
|
+
# result from API is typically {"results": [...]}
|
|
136
|
+
results = result if isinstance(result, list) else result.get("results", [result])
|
|
137
|
+
if not results:
|
|
138
|
+
console.print(f" [{DIM_COLOR}]No memories extracted.[/]")
|
|
139
|
+
return
|
|
140
|
+
|
|
141
|
+
console.print()
|
|
142
|
+
for r in results:
|
|
143
|
+
# Detect async PENDING response from Platform API
|
|
144
|
+
if r.get("status") == "PENDING":
|
|
145
|
+
event_id = r.get("event_id", "")[:8]
|
|
146
|
+
icon = f"[{ACCENT_COLOR}]{_sym('⧗', '...')}[/]"
|
|
147
|
+
parts = [f" {icon} [{DIM_COLOR}]{'Queued':<10}[/]"]
|
|
148
|
+
parts.append("[white]Processing in background[/]")
|
|
149
|
+
if event_id:
|
|
150
|
+
parts.append(f"[{DIM_COLOR}](event {event_id})[/]")
|
|
151
|
+
console.print(" ".join(parts))
|
|
152
|
+
continue
|
|
153
|
+
|
|
154
|
+
event = r.get("event", "ADD")
|
|
155
|
+
memory = r.get("memory") or r.get("text") or r.get("content") or r.get("data") or ""
|
|
156
|
+
mem_id = (r.get("id") or r.get("memory_id") or "")[:8]
|
|
157
|
+
|
|
158
|
+
if event == "ADD":
|
|
159
|
+
icon = f"[{SUCCESS_COLOR}]+[/]"
|
|
160
|
+
label = "Added"
|
|
161
|
+
elif event == "UPDATE":
|
|
162
|
+
icon = f"[{ACCENT_COLOR}]~[/]"
|
|
163
|
+
label = "Updated"
|
|
164
|
+
elif event == "DELETE":
|
|
165
|
+
icon = "[red]-[/]"
|
|
166
|
+
label = "Deleted"
|
|
167
|
+
elif event == "NOOP":
|
|
168
|
+
icon = f"[{DIM_COLOR}]·[/]"
|
|
169
|
+
label = "No change"
|
|
170
|
+
else:
|
|
171
|
+
icon = f"[{DIM_COLOR}]?[/]"
|
|
172
|
+
label = event
|
|
173
|
+
|
|
174
|
+
# Build the display line
|
|
175
|
+
parts = [f" {icon} [{DIM_COLOR}]{label:<10}[/]"]
|
|
176
|
+
if memory:
|
|
177
|
+
parts.append(f"[white]{memory}[/]")
|
|
178
|
+
if mem_id:
|
|
179
|
+
parts.append(f"[{DIM_COLOR}]({mem_id})[/]")
|
|
180
|
+
console.print(" ".join(parts))
|
|
181
|
+
console.print()
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def format_json_envelope(
|
|
185
|
+
console: Console,
|
|
186
|
+
*,
|
|
187
|
+
command: str,
|
|
188
|
+
data: Any,
|
|
189
|
+
duration_ms: int | None = None,
|
|
190
|
+
scope: dict | None = None,
|
|
191
|
+
count: int | None = None,
|
|
192
|
+
status: str = "success",
|
|
193
|
+
error: str | None = None,
|
|
194
|
+
) -> None:
|
|
195
|
+
"""Output structured JSON envelope for AI agent consumption."""
|
|
196
|
+
envelope: dict[str, Any] = {
|
|
197
|
+
"status": status,
|
|
198
|
+
"command": command,
|
|
199
|
+
}
|
|
200
|
+
if duration_ms is not None:
|
|
201
|
+
envelope["duration_ms"] = duration_ms
|
|
202
|
+
if scope is not None:
|
|
203
|
+
envelope["scope"] = scope
|
|
204
|
+
if count is not None:
|
|
205
|
+
envelope["count"] = count
|
|
206
|
+
if error:
|
|
207
|
+
envelope["error"] = error
|
|
208
|
+
envelope["data"] = data
|
|
209
|
+
console.print_json(json.dumps(envelope, default=str))
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def print_result_summary(
|
|
213
|
+
console: Console,
|
|
214
|
+
count: int,
|
|
215
|
+
*,
|
|
216
|
+
duration_secs: float | None = None,
|
|
217
|
+
page: int | None = None,
|
|
218
|
+
**scope_ids: str | None,
|
|
219
|
+
) -> None:
|
|
220
|
+
"""Print a summary footer after result lists."""
|
|
221
|
+
parts = [f"{count} result{'s' if count != 1 else ''}"]
|
|
222
|
+
if page is not None:
|
|
223
|
+
parts.append(f"page {page}")
|
|
224
|
+
scope_parts = [f"{k.replace('_', ' ')}={v}" for k, v in scope_ids.items() if v]
|
|
225
|
+
if scope_parts:
|
|
226
|
+
parts.append(", ".join(scope_parts))
|
|
227
|
+
if duration_secs is not None:
|
|
228
|
+
parts.append(f"{duration_secs:.2f}s")
|
|
229
|
+
|
|
230
|
+
summary = " · ".join(parts)
|
|
231
|
+
console.print(f" [{DIM_COLOR}]{summary}[/]")
|
|
232
|
+
console.print()
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def _format_date(dt_str: str | None) -> str | None:
|
|
236
|
+
if not dt_str:
|
|
237
|
+
return None
|
|
238
|
+
try:
|
|
239
|
+
dt = datetime.fromisoformat(dt_str.replace("Z", "+00:00"))
|
|
240
|
+
return dt.strftime("%Y-%m-%d")
|
|
241
|
+
except (ValueError, AttributeError):
|
|
242
|
+
return str(dt_str)[:10] if dt_str else None
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mem0-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The official CLI for mem0 — the memory layer for AI agents
|
|
5
|
+
Author-email: "mem0.ai" <founders@mem0.ai>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Keywords: agents,ai,cli,mem0,memory
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Requires-Dist: httpx>=0.24.0
|
|
19
|
+
Requires-Dist: rich>=13.0.0
|
|
20
|
+
Requires-Dist: typer>=0.9.0
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
24
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
25
|
+
Provides-Extra: oss
|
|
26
|
+
Requires-Dist: mem0ai>=0.1.0; extra == 'oss'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# mem0 CLI
|
|
30
|
+
|
|
31
|
+
The official command-line interface for [mem0](https://mem0.ai) — the memory layer for AI agents.
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install mem0-cli
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Set up your configuration
|
|
43
|
+
mem0 init
|
|
44
|
+
|
|
45
|
+
# Add a memory
|
|
46
|
+
mem0 add "I prefer dark mode and use vim keybindings" --user-id alice
|
|
47
|
+
|
|
48
|
+
# Search memories
|
|
49
|
+
mem0 search "What are Alice's preferences?" --user-id alice
|
|
50
|
+
|
|
51
|
+
# List all memories
|
|
52
|
+
mem0 list --user-id alice
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## License
|
|
56
|
+
|
|
57
|
+
Apache-2.0
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
mem0_cli/__init__.py,sha256=1GKZL4QjClY1AD4w4HbQquF5nvNT1kn44dsuY0fBAL4,96
|
|
2
|
+
mem0_cli/__main__.py,sha256=bfYlOrVq4kv2QX1wjtYBCAjS0eSsLi0qmyT6TSQDv9A,86
|
|
3
|
+
mem0_cli/app.py,sha256=aCKP2A429wprh15xM2Xx3Xoxgviiu2434vHp8t8O_Ds,37882
|
|
4
|
+
mem0_cli/branding.py,sha256=JnDxyNFXAvz0awiHM2WB0vva-HZckGhdTqMdAioYhzM,4432
|
|
5
|
+
mem0_cli/config.py,sha256=nIZXMkKHS8fPL-p2Z32z3ofK0FZNwo5H1kwuU--BtTA,4962
|
|
6
|
+
mem0_cli/output.py,sha256=5RphhMqxdw2gF3qrTp0lJTJKoBZELkPaRw7FUedPm4I,7865
|
|
7
|
+
mem0_cli/backend/__init__.py,sha256=sGfi-FMQvISsSzP0fCQ1J7_01cTPorOQuXekyyHhX-s,140
|
|
8
|
+
mem0_cli/backend/base.py,sha256=UMgsy6gPNcfqw-gfqaJag8D1eppTCxUnHbX_ANHNXjo,2854
|
|
9
|
+
mem0_cli/backend/platform.py,sha256=DyE9nROJEas9S_6C33-4c0QO7nfUUuR1UtKB7tRBkao,10771
|
|
10
|
+
mem0_cli/commands/__init__.py,sha256=gQ6tnU0Rvm0-ESWFUBU-KDl5dpNOpUTG509hXOQQjwY,27
|
|
11
|
+
mem0_cli/commands/config_cmd.py,sha256=MCSsUnBOiof1jDP9NEnhAH_OMy1SjL_q9okrP54KkcE,3223
|
|
12
|
+
mem0_cli/commands/entities.py,sha256=yniG3zJOcw-4r3C3DV4VJ_R2ULj-yzenIMLWJZq0Yg4,4137
|
|
13
|
+
mem0_cli/commands/init_cmd.py,sha256=R8nyJDC--22imTS0Fio0tstjLQfdm8bxOiA8FjI4Y14,6132
|
|
14
|
+
mem0_cli/commands/memory.py,sha256=B6upEu3t0AMFeyr7JOtoIRbtlYAXasa2OEQZEukagVk,14069
|
|
15
|
+
mem0_cli/commands/utils.py,sha256=uTTQ0aICKg6veL-Ee2Bb8ADFDZccnFIohVLetc2THIQ,4056
|
|
16
|
+
mem0_cli-0.1.0.dist-info/METADATA,sha256=E884sL35pYWrT8EU9TVAJtEDlhIePVilMurd7zfZAec,1512
|
|
17
|
+
mem0_cli-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
18
|
+
mem0_cli-0.1.0.dist-info/entry_points.txt,sha256=KK5vcLwfiOuxMhPvSzhg3Cg67iCUz10YRxExoBrFwQo,43
|
|
19
|
+
mem0_cli-0.1.0.dist-info/RECORD,,
|