mem0-cli 0.2.5__tar.gz → 0.2.7__tar.gz

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.
Files changed (29) hide show
  1. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/PKG-INFO +1 -1
  2. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/pyproject.toml +1 -1
  3. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/app.py +59 -0
  4. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/commands/agent_mode_cmd.py +1 -1
  5. mem0_cli-0.2.7/src/mem0_cli/commands/agent_rush_cmd.py +132 -0
  6. mem0_cli-0.2.7/src/mem0_cli/commands/whoami_cmd.py +25 -0
  7. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/config.py +14 -0
  8. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/.gitignore +0 -0
  9. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/README.md +0 -0
  10. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/__init__.py +0 -0
  11. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/__main__.py +0 -0
  12. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/agent_detect.py +0 -0
  13. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/backend/__init__.py +0 -0
  14. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/backend/base.py +0 -0
  15. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/backend/platform.py +0 -0
  16. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/branding.py +0 -0
  17. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/commands/__init__.py +0 -0
  18. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/commands/config_cmd.py +0 -0
  19. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/commands/entities.py +0 -0
  20. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/commands/events_cmd.py +0 -0
  21. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/commands/identify_cmd.py +0 -0
  22. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/commands/init_cmd.py +0 -0
  23. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/commands/memory.py +0 -0
  24. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/commands/utils.py +0 -0
  25. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/output.py +0 -0
  26. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/plugin_sync.py +0 -0
  27. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/state.py +0 -0
  28. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/telemetry.py +0 -0
  29. {mem0_cli-0.2.5 → mem0_cli-0.2.7}/src/mem0_cli/telemetry_sender.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mem0-cli
3
- Version: 0.2.5
3
+ Version: 0.2.7
4
4
  Summary: The official CLI for mem0 — the memory layer for AI agents
5
5
  Author-email: "mem0.ai" <founders@mem0.ai>
6
6
  License-Expression: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "mem0-cli"
7
- version = "0.2.5"
7
+ version = "0.2.7"
8
8
  description = "The official CLI for mem0 — the memory layer for AI agents"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -914,6 +914,65 @@ def identify(
914
914
  run_identify(name)
915
915
 
916
916
 
917
+ @app.command(name="whoami", rich_help_panel="Setup")
918
+ def whoami_cmd() -> None:
919
+ """Print your AGENTRUSH identifier (default_user_id).
920
+
921
+ Example:
922
+ mem0 whoami
923
+ """
924
+ from mem0_cli.commands.whoami_cmd import run_whoami
925
+
926
+ run_whoami()
927
+
928
+
929
+ # ── AGENTRUSH sub-app ─────────────────────────────────────────────────────
930
+
931
+ agent_rush_app = typer.Typer(
932
+ name="agent-rush",
933
+ help="AGENTRUSH game commands",
934
+ no_args_is_help=True,
935
+ rich_markup_mode="rich",
936
+ )
937
+
938
+
939
+ @agent_rush_app.callback(invoke_without_command=True)
940
+ def _agent_rush_callback(ctx: typer.Context) -> None:
941
+ if ctx.invoked_subcommand:
942
+ _fire_telemetry(f"agent-rush.{ctx.invoked_subcommand}")
943
+
944
+
945
+ @agent_rush_app.command(name="add")
946
+ def agent_rush_add(
947
+ content: str = typer.Argument(..., help="Memory content (50-1000 characters, no URLs)."),
948
+ ) -> None:
949
+ """Submit a memory to AGENTRUSH.
950
+
951
+ Example:
952
+ mem0 agent-rush add "I enjoy solving constraint-satisfaction problems."
953
+ """
954
+ from mem0_cli.commands.agent_rush_cmd import run_agent_rush_add
955
+
956
+ run_agent_rush_add(content)
957
+
958
+
959
+ @agent_rush_app.command(name="search")
960
+ def agent_rush_search(
961
+ query: str = typer.Argument(..., help="Search query."),
962
+ ) -> None:
963
+ """Search AGENTRUSH memories.
964
+
965
+ Example:
966
+ mem0 agent-rush search "constraint satisfaction"
967
+ """
968
+ from mem0_cli.commands.agent_rush_cmd import run_agent_rush_search
969
+
970
+ run_agent_rush_search(query)
971
+
972
+
973
+ app.add_typer(agent_rush_app, name="agent-rush", rich_help_panel="Setup")
974
+
975
+
917
976
  # (entity_app registered at module level, below sub-group definitions)
918
977
 
919
978
 
@@ -218,7 +218,7 @@ def claim_via_otp(config: Mem0Config, *, email: str, code: str | None = None) ->
218
218
  print_error(err_console, f"Claim failed: {detail}")
219
219
  if code_str == "email_already_claimed":
220
220
  console.print(
221
- f" [{DIM_COLOR}]Tip: this email already has a Mem0 account. Sign in there and run `mem0 link <key>` to attach this agent.[/]"
221
+ f" [{DIM_COLOR}]Tip: this email already has a Mem0 account. Sign in at app.mem0.ai with your existing credentials.[/]"
222
222
  )
223
223
  raise typer.Exit(1)
224
224
 
@@ -0,0 +1,132 @@
1
+ """mem0 agent-rush — AGENTRUSH game commands.
2
+
3
+ Wraps the platform's /v1/agent-rush/{memories/, memories/search/} endpoints.
4
+ Hardcoded routing; no flags needed.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import sys
10
+ from datetime import datetime, timezone
11
+
12
+ import httpx
13
+ import typer
14
+ from rich.console import Console
15
+
16
+ from mem0_cli.branding import print_error, print_success
17
+ from mem0_cli.config import load_config, save_config
18
+
19
+ console = Console()
20
+ err_console = Console(stderr=True)
21
+
22
+ _PII_WARNING_LINES = (
23
+ "",
24
+ "[yellow]⚠️ AGENTRUSH memories are PUBLIC — visible to any other player.[/yellow]",
25
+ "[yellow] Do not include real names, emails, secrets, work content, or PII.[/yellow]",
26
+ "",
27
+ )
28
+
29
+ _SOURCE_HEADERS = {
30
+ "X-Mem0-Source": "cli",
31
+ "X-Mem0-Client-Language": "python",
32
+ "X-Mem0-Mode": "agent-rush",
33
+ }
34
+
35
+ _ERROR_HINTS = {
36
+ "agentrush_search_first": "Run 3 'mem0 agent-rush search' commands before adding.",
37
+ "agentrush_search_quota": "You've used your 3 lifetime searches.",
38
+ "agentrush_add_quota": "You've used your 3 lifetime adds.",
39
+ "agentrush_not_agent_mode": "Re-run 'mem0 init --agent' to bootstrap an agent-mode key.",
40
+ "agentrush_length": "Memory text must be 50-1000 characters.",
41
+ "agentrush_no_urls": "URLs are not allowed.",
42
+ "agentrush_blocklist": "Content contains a blocked term.",
43
+ "agentrush_global_quota": "Event-wide cap reached. Try again later.",
44
+ "agentrush_not_provisioned": "AGENTRUSH is not provisioned in this environment.",
45
+ }
46
+
47
+
48
+ def _call(path: str, body: dict) -> dict:
49
+ config = load_config()
50
+ if not config.platform.api_key:
51
+ print_error(err_console, "Not initialized. Run `mem0 init --agent` first.")
52
+ raise typer.Exit(1)
53
+ base_url = (config.platform.base_url or "https://api.mem0.ai").rstrip("/")
54
+ try:
55
+ with httpx.Client(timeout=30.0) as client:
56
+ resp = client.post(
57
+ f"{base_url}{path}",
58
+ headers={
59
+ **_SOURCE_HEADERS,
60
+ "Authorization": f"Token {config.platform.api_key}",
61
+ "Content-Type": "application/json",
62
+ },
63
+ json=body,
64
+ )
65
+ except httpx.HTTPError as exc:
66
+ print_error(err_console, f"Network error: {exc}")
67
+ raise typer.Exit(1) from exc
68
+ try:
69
+ data = resp.json()
70
+ except Exception:
71
+ data = {}
72
+ if resp.status_code >= 400:
73
+ code = (
74
+ (data.get("error") or {}).get("code", "unknown")
75
+ if isinstance(data, dict)
76
+ else "unknown"
77
+ )
78
+ print_error(err_console, f"AGENTRUSH error: {code}")
79
+ hint = _ERROR_HINTS.get(code)
80
+ if hint:
81
+ console.print(f" [dim]{hint}[/dim]")
82
+ raise typer.Exit(1)
83
+ return data
84
+
85
+
86
+ def _ensure_warning_acknowledged() -> None:
87
+ """Block the first interactive add on the PII warning; pass-through for agents.
88
+
89
+ Interactive (TTY): show prompt, require explicit 'y', persist
90
+ `agent_rush.acknowledged_at` so we never ask the same machine twice.
91
+
92
+ Non-interactive (no TTY — typical when an agent runs the CLI): surface
93
+ the warning to stderr for the human reading the agent transcript and
94
+ proceed without prompting (agents can't answer y/N).
95
+ """
96
+ config = load_config()
97
+ if config.agent_rush.acknowledged_at:
98
+ return
99
+
100
+ is_tty = sys.stdin.isatty() and sys.stdout.isatty()
101
+ if not is_tty:
102
+ for line in _PII_WARNING_LINES:
103
+ err_console.print(line)
104
+ return
105
+
106
+ for line in _PII_WARNING_LINES:
107
+ console.print(line)
108
+ answer = typer.prompt(" Continue? [y/N]", default="N", show_default=False).strip().lower()
109
+ if answer not in ("y", "yes"):
110
+ print_error(err_console, "Aborted.")
111
+ raise typer.Exit(1)
112
+
113
+ config.agent_rush.acknowledged_at = datetime.now(timezone.utc).isoformat()
114
+ save_config(config)
115
+
116
+
117
+ def run_agent_rush_add(content: str) -> None:
118
+ _ensure_warning_acknowledged()
119
+ result = _call("/v1/agent-rush/memories/", {"content": content})
120
+ event_id = result.get("event_id", "?")
121
+ print_success(console, f"Memory submitted (event_id: {event_id})")
122
+
123
+
124
+ def run_agent_rush_search(query: str) -> None:
125
+ result = _call("/v1/agent-rush/memories/search/", {"query": query})
126
+ memories = result.get("results") or result.get("memories") or []
127
+ if not memories:
128
+ console.print("[dim](no results)[/dim]")
129
+ return
130
+ for i, m in enumerate(memories[:5], start=1):
131
+ text = m.get("memory") if isinstance(m, dict) else str(m)
132
+ console.print(f" {i}. {text}")
@@ -0,0 +1,25 @@
1
+ """mem0 whoami — print the active agent's default_user_id (AGENTRUSH identifier)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import typer
6
+ from rich.console import Console
7
+
8
+ from mem0_cli.branding import BRAND_COLOR, print_error, print_info
9
+ from mem0_cli.config import load_config
10
+
11
+ console = Console()
12
+ err_console = Console(stderr=True)
13
+
14
+
15
+ def run_whoami() -> None:
16
+ config = load_config()
17
+ session_id = config.platform.default_user_id if config.platform else None
18
+ if not session_id:
19
+ print_error(
20
+ err_console,
21
+ "No default_user_id found. Run `mem0 init --agent` first.",
22
+ )
23
+ raise typer.Exit(1)
24
+ console.print(f"Your AGENTRUSH identifier: [{BRAND_COLOR}]{session_id}[/{BRAND_COLOR}]")
25
+ print_info(console, "Find your row at https://mem0.ai/agentrush")
@@ -51,12 +51,20 @@ class TelemetryConfig:
51
51
  anonymous_id: str = ""
52
52
 
53
53
 
54
+ @dataclass
55
+ class AgentRushConfig:
56
+ # ISO timestamp the human acknowledged the "memories are public" warning.
57
+ # Empty until first interactive `mem0 agent-rush add`.
58
+ acknowledged_at: str = ""
59
+
60
+
54
61
  @dataclass
55
62
  class Mem0Config:
56
63
  version: int = CONFIG_VERSION
57
64
  defaults: DefaultsConfig = field(default_factory=DefaultsConfig)
58
65
  platform: PlatformConfig = field(default_factory=PlatformConfig)
59
66
  telemetry: TelemetryConfig = field(default_factory=TelemetryConfig)
67
+ agent_rush: AgentRushConfig = field(default_factory=AgentRushConfig)
60
68
 
61
69
 
62
70
  SHORT_KEY_ALIASES: dict[str, str] = {
@@ -105,6 +113,9 @@ def load_config() -> Mem0Config:
105
113
  telemetry = data.get("telemetry", {})
106
114
  config.telemetry.anonymous_id = telemetry.get("anonymous_id", "")
107
115
 
116
+ agent_rush = data.get("agent_rush", {})
117
+ config.agent_rush.acknowledged_at = agent_rush.get("acknowledged_at", "")
118
+
108
119
  # Environment variable overrides
109
120
  env_key = os.environ.get("MEM0_API_KEY")
110
121
  if env_key:
@@ -158,6 +169,9 @@ def save_config(config: Mem0Config) -> None:
158
169
  "telemetry": {
159
170
  "anonymous_id": config.telemetry.anonymous_id,
160
171
  },
172
+ "agent_rush": {
173
+ "acknowledged_at": config.agent_rush.acknowledged_at,
174
+ },
161
175
  }
162
176
 
163
177
  with open(CONFIG_FILE, "w") as f:
File without changes
File without changes
File without changes