mnemosyne-memory 2.1__tar.gz → 2.2__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 (78) hide show
  1. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/CHANGELOG.md +28 -0
  2. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/PKG-INFO +30 -2
  3. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/README.md +29 -1
  4. mnemosyne_memory-2.2/hermes_memory_provider/cli.py +260 -0
  5. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/hermes_plugin/tools.py +71 -6
  6. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/__init__.py +1 -1
  7. mnemosyne_memory-2.2/mnemosyne/core/importers/__init__.py +152 -0
  8. mnemosyne_memory-2.2/mnemosyne/core/importers/agentic.py +391 -0
  9. mnemosyne_memory-2.2/mnemosyne/core/importers/base.py +245 -0
  10. mnemosyne_memory-2.2/mnemosyne/core/importers/cognee.py +290 -0
  11. mnemosyne_memory-2.2/mnemosyne/core/importers/honcho.py +283 -0
  12. mnemosyne_memory-2.2/mnemosyne/core/importers/letta.py +313 -0
  13. mnemosyne_memory-2.2/mnemosyne/core/importers/mem0.py +378 -0
  14. mnemosyne_memory-2.2/mnemosyne/core/importers/supermemory.py +260 -0
  15. mnemosyne_memory-2.2/mnemosyne/core/importers/zep.py +322 -0
  16. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne_memory.egg-info/PKG-INFO +30 -2
  17. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne_memory.egg-info/SOURCES.txt +9 -0
  18. mnemosyne_memory-2.1/hermes_memory_provider/cli.py +0 -137
  19. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/CONTRIBUTING.md +0 -0
  20. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/LICENSE +0 -0
  21. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/MANIFEST.in +0 -0
  22. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/UPDATING.md +0 -0
  23. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/assets/mnemosyne.jpg +0 -0
  24. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/docs/README.md +0 -0
  25. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/docs/api-reference.md +0 -0
  26. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/docs/architecture.md +0 -0
  27. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/docs/changelog.md +0 -0
  28. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/docs/comparison.md +0 -0
  29. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/docs/configuration.md +0 -0
  30. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/docs/getting-started.md +0 -0
  31. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/docs/hermes-integration.md +0 -0
  32. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/docs/llm-installation-guide.md +0 -0
  33. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/hermes_memory_provider/__init__.py +0 -0
  34. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/hermes_plugin/__init__.py +0 -0
  35. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/cli.py +0 -0
  36. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/__init__.py +0 -0
  37. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/aaak.py +0 -0
  38. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/banks.py +0 -0
  39. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/beam.py +0 -0
  40. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/cost_log.py +0 -0
  41. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/embeddings.py +0 -0
  42. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/entities.py +0 -0
  43. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/extraction.py +0 -0
  44. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/local_llm.py +0 -0
  45. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/memory.py +0 -0
  46. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/patterns.py +0 -0
  47. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/plugins.py +0 -0
  48. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/streaming.py +0 -0
  49. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/token_counter.py +0 -0
  50. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/core/triples.py +0 -0
  51. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/diagnose.py +0 -0
  52. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/dr/__init__.py +0 -0
  53. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/dr/recovery.py +0 -0
  54. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/install.py +0 -0
  55. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/mcp_server.py +0 -0
  56. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne/mcp_tools.py +0 -0
  57. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne_memory.egg-info/dependency_links.txt +0 -0
  58. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne_memory.egg-info/entry_points.txt +0 -0
  59. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne_memory.egg-info/requires.txt +0 -0
  60. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/mnemosyne_memory.egg-info/top_level.txt +0 -0
  61. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/pyproject.toml +0 -0
  62. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/setup.cfg +0 -0
  63. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/setup.py +0 -0
  64. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_beam.py +0 -0
  65. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_configurable_scoring.py +0 -0
  66. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_entities.py +0 -0
  67. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_entity_integration.py +0 -0
  68. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_extraction.py +0 -0
  69. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_extraction_integration.py +0 -0
  70. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_local_llm.py +0 -0
  71. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_mcp_server.py +0 -0
  72. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_memory_banks.py +0 -0
  73. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_mnemosyne_stats.py +0 -0
  74. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_multi_agent_identity.py +0 -0
  75. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_patterns.py +0 -0
  76. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_plugins.py +0 -0
  77. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_streaming.py +0 -0
  78. {mnemosyne_memory-2.1 → mnemosyne_memory-2.2}/tests/test_temporal_recall.py +0 -0
@@ -5,6 +5,34 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Simple Versioning](https://github.com/AxDSan/mnemosyne) (MAJOR.MINOR).
7
7
 
8
+ ## [2.2] — 2026-05-02
9
+
10
+ ### Added
11
+
12
+ **Cross-Provider Importers — migrate from any memory platform**
13
+ - New `mnemosyne/core/importers/` module with 6 provider importers
14
+ - **Mem0:** SDK pagination → REST → structured export fallback chain; preserves user/agent/app scoping
15
+ - **Letta (MemGPT):** AgentFile `.af` format parsing (JSON/YAML/TOML); memory blocks → working_memory, messages → episodic
16
+ - **Zep:** users → sessions → `memory.get()` per-session iteration; messages + summaries + facts extraction
17
+ - **Cognee:** `get_graph_data()` nodes/edges extraction; nodes → episodic memories, edges → triples
18
+ - **Honcho:** peers → sessions → `context()` + messages; peer identity preserved as author_id
19
+ - **SuperMemory:** `documents.list()` + `search.execute()`; container tags mapped to channel_id
20
+ - **Agentic importer:** generates ready-to-run Python migration scripts and AI agent instructions for all 6 providers
21
+
22
+ **CLI: `hermes mnemosyne import` extended**
23
+ - `--from <provider>` — import directly from Mem0, Letta, Zep, etc.
24
+ - `--list-providers` — show all supported providers with docs links
25
+ - `--generate-script` — generate a migration script for any provider
26
+ - `--agentic` — output instructions to give your AI agent for extraction
27
+ - `--dry-run` — validate and transform without writing
28
+
29
+ **Plugin tool updated**
30
+ - `mnemosyne_import` schema extended with `provider`, `api_key`, `user_id`, `agent_id`, `dry_run`, `channel_id` params
31
+
32
+ ### Changed
33
+
34
+ - README: added "Migrate from other memory providers" section with examples
35
+
8
36
  ## [2.1] — 2026-05-02
9
37
 
10
38
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mnemosyne-memory
3
- Version: 2.1
3
+ Version: 2.2
4
4
  Summary: The Zero-Dependency, Sub-Millisecond AI Memory System
5
5
  Home-page: https://github.com/AxDSan/mnemosyne
6
6
  Author: Abdias J
@@ -50,7 +50,7 @@ Dynamic: requires-python
50
50
  > Native, zero-cloud memory for AI agents. SQLite-backed. Sub-millisecond. Fully private.
51
51
 
52
52
  [![Python](https://img.shields.io/badge/Python-3.9+-blue.svg)](https://python.org)
53
- [![PyPI](https://img.shields.io/pypi/v/mnemosyne-memory.svg?v=2.1)](https://pypi.org/project/mnemosyne-memory/)
53
+ [![PyPI](https://img.shields.io/pypi/v/mnemosyne-memory.svg?v=2.2)](https://pypi.org/project/mnemosyne-memory/)
54
54
  [![SQLite](https://img.shields.io/badge/SQLite-3.35+-green.svg)](https://sqlite.org/codeofethics.html)
55
55
  [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
56
56
  [![CI](https://github.com/AxDSan/mnemosyne/actions/workflows/ci.yml/badge.svg)](https://github.com/AxDSan/mnemosyne/actions/workflows/ci.yml)
@@ -553,6 +553,34 @@ hermes mnemosyne export --output mnemosyne_backup.json
553
553
  hermes mnemosyne import --input mnemosyne_backup.json
554
554
  ```
555
555
 
556
+ ### Migrate from other memory providers
557
+
558
+ Import directly from 6 supported providers into Mnemosyne:
559
+
560
+ ```bash
561
+ # List all supported providers
562
+ hermes mnemosyne import --list-providers
563
+
564
+ # Mem0 → Mnemosyne
565
+ hermes mnemosyne import --from mem0 --api-key sk-xxx
566
+
567
+ # Letta → Mnemosyne (offline .af file)
568
+ hermes mnemosyne import --from letta --agent-file-path ./agent.af
569
+
570
+ # Zep → Mnemosyne
571
+ hermes mnemosyne import --from zep --api-key sk-xxx --max-sessions 100
572
+
573
+ # Generate a migration script for any provider
574
+ hermes mnemosyne import --from mem0 --generate-script --output-script migrate.py
575
+
576
+ # Use AI agent extraction (no SDK needed)
577
+ hermes mnemosyne import --from zep --agentic
578
+ ```
579
+
580
+ **Supported providers:** Mem0, Letta (MemGPT), Zep, Cognee, Honcho, SuperMemory
581
+
582
+ All importers preserve metadata, timestamps, user/agent identity, and relationships (graph edges → triples). Use `--dry-run` to validate without writing.
583
+
556
584
  ---
557
585
 
558
586
  ## Environment Variables
@@ -5,7 +5,7 @@
5
5
  > Native, zero-cloud memory for AI agents. SQLite-backed. Sub-millisecond. Fully private.
6
6
 
7
7
  [![Python](https://img.shields.io/badge/Python-3.9+-blue.svg)](https://python.org)
8
- [![PyPI](https://img.shields.io/pypi/v/mnemosyne-memory.svg?v=2.1)](https://pypi.org/project/mnemosyne-memory/)
8
+ [![PyPI](https://img.shields.io/pypi/v/mnemosyne-memory.svg?v=2.2)](https://pypi.org/project/mnemosyne-memory/)
9
9
  [![SQLite](https://img.shields.io/badge/SQLite-3.35+-green.svg)](https://sqlite.org/codeofethics.html)
10
10
  [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
11
11
  [![CI](https://github.com/AxDSan/mnemosyne/actions/workflows/ci.yml/badge.svg)](https://github.com/AxDSan/mnemosyne/actions/workflows/ci.yml)
@@ -508,6 +508,34 @@ hermes mnemosyne export --output mnemosyne_backup.json
508
508
  hermes mnemosyne import --input mnemosyne_backup.json
509
509
  ```
510
510
 
511
+ ### Migrate from other memory providers
512
+
513
+ Import directly from 6 supported providers into Mnemosyne:
514
+
515
+ ```bash
516
+ # List all supported providers
517
+ hermes mnemosyne import --list-providers
518
+
519
+ # Mem0 → Mnemosyne
520
+ hermes mnemosyne import --from mem0 --api-key sk-xxx
521
+
522
+ # Letta → Mnemosyne (offline .af file)
523
+ hermes mnemosyne import --from letta --agent-file-path ./agent.af
524
+
525
+ # Zep → Mnemosyne
526
+ hermes mnemosyne import --from zep --api-key sk-xxx --max-sessions 100
527
+
528
+ # Generate a migration script for any provider
529
+ hermes mnemosyne import --from mem0 --generate-script --output-script migrate.py
530
+
531
+ # Use AI agent extraction (no SDK needed)
532
+ hermes mnemosyne import --from zep --agentic
533
+ ```
534
+
535
+ **Supported providers:** Mem0, Letta (MemGPT), Zep, Cognee, Honcho, SuperMemory
536
+
537
+ All importers preserve metadata, timestamps, user/agent identity, and relationships (graph edges → triples). Use `--dry-run` to validate without writing.
538
+
511
539
  ---
512
540
 
513
541
  ## Environment Variables
@@ -0,0 +1,260 @@
1
+ """CLI commands for Mnemosyne memory provider.
2
+
3
+ Available via: hermes mnemosyne <subcommand>
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import json
9
+ import sys
10
+ from pathlib import Path
11
+
12
+ _mnemosyne_root = Path(__file__).resolve().parent.parent
13
+ if str(_mnemosyne_root) not in sys.path:
14
+ sys.path.insert(0, str(_mnemosyne_root))
15
+
16
+
17
+ def register_cli(subparser):
18
+ """Register CLI subcommands for ``hermes mnemosyne``."""
19
+ mn_cmds = subparser.add_subparsers(dest="mnemosyne_cmd")
20
+
21
+ stats_cmd = mn_cmds.add_parser("stats", help="Show memory statistics")
22
+ stats_cmd.add_argument("--global", "-g", action="store_true", help="Show global stats across all sessions")
23
+
24
+ sleep_cmd = mn_cmds.add_parser("sleep", help="Run consolidation cycle")
25
+ sleep_cmd.add_argument("--all-sessions", action="store_true", help="Consolidate eligible old working memories across all sessions")
26
+ sleep_cmd.add_argument("--dry-run", action="store_true", help="Report what would be consolidated without writing changes")
27
+ mn_cmds.add_parser("version", help="Show Mnemosyne version")
28
+
29
+ inspect_cmd = mn_cmds.add_parser("inspect", help="Search memories")
30
+ inspect_cmd.add_argument("query", nargs="?", default="", help="Search query")
31
+ inspect_cmd.add_argument("--limit", type=int, default=10, help="Max results")
32
+
33
+ mn_cmds.add_parser("clear", help="Clear scratchpad")
34
+
35
+ export_cmd = mn_cmds.add_parser("export", help="Export all memories to a JSON file")
36
+ export_cmd.add_argument("--output", "-o", type=str, required=True, help="Output JSON file path")
37
+
38
+ import_cmd = mn_cmds.add_parser("import", help="Import memories from a JSON file or another provider")
39
+ import_cmd.add_argument("--input", "-i", type=str, help="Input JSON file path (for file imports)")
40
+ import_cmd.add_argument("--force", action="store_true", help="Overwrite existing records (file import)")
41
+ import_cmd.add_argument("--from", dest="from_provider", type=str, help="Provider to import from (e.g., 'mem0')")
42
+ import_cmd.add_argument("--api-key", type=str, help="Provider API key (or set env var)")
43
+ import_cmd.add_argument("--user-id", type=str, help="Filter by user ID (provider-specific)")
44
+ import_cmd.add_argument("--agent-id", type=str, help="Filter by agent ID (provider-specific)")
45
+ import_cmd.add_argument("--base-url", type=str, help="Provider base URL (for self-hosted)")
46
+ import_cmd.add_argument("--dry-run", action="store_true", help="Validate but don't import")
47
+ import_cmd.add_argument("--session-id", type=str, help="Override session for imported memories")
48
+ import_cmd.add_argument("--channel-id", type=str, help="Channel for imported memories")
49
+ import_cmd.add_argument("--list-providers", action="store_true", help="List supported import providers")
50
+ import_cmd.add_argument("--generate-script", action="store_true", help="Generate a migration script for the provider")
51
+ import_cmd.add_argument("--agentic", action="store_true", help="Generate agent migration instructions (prompt to give your AI agent)")
52
+ import_cmd.add_argument("--output-script", type=str, help="Save generated script to file")
53
+
54
+ subparser.set_defaults(func=mnemosyne_command)
55
+
56
+
57
+ def mnemosyne_command(args):
58
+ """Dispatch ``hermes mnemosyne <subcommand>``."""
59
+ cmd = getattr(args, "mnemosyne_cmd", None)
60
+ if not cmd:
61
+ print("Usage: hermes mnemosyne {stats|sleep|inspect|clear}")
62
+ return 1
63
+
64
+ try:
65
+ from mnemosyne.core.beam import BeamMemory
66
+ beam = BeamMemory(session_id="hermes_default")
67
+ except Exception as e:
68
+ print(f"Error: Mnemosyne not available: {e}")
69
+ return 1
70
+
71
+ if cmd == "stats":
72
+ if getattr(args, "global", False):
73
+ working = beam.get_global_working_stats()
74
+ else:
75
+ working = beam.get_working_stats()
76
+ episodic = beam.get_episodic_stats()
77
+ print(json.dumps({"working": working, "episodic": episodic}, indent=2))
78
+
79
+ elif cmd == "version":
80
+ from mnemosyne import __version__, __author__
81
+ print(f"Mnemosyne {__version__} by {__author__}")
82
+
83
+ elif cmd == "sleep":
84
+ dry_run = bool(getattr(args, "dry_run", False))
85
+ if getattr(args, "all_sessions", False):
86
+ result = beam.sleep_all_sessions(dry_run=dry_run)
87
+ else:
88
+ result = beam.sleep(dry_run=dry_run)
89
+ print(json.dumps(result, indent=2))
90
+
91
+ elif cmd == "inspect":
92
+ query = getattr(args, "query", "") or ""
93
+ limit = getattr(args, "limit", 10)
94
+ if not query:
95
+ query = input("Search query: ")
96
+ results = beam.recall(query, top_k=limit)
97
+ print(f"Results for '{query}': {len(results)}")
98
+ for i, r in enumerate(results, 1):
99
+ content = r.get("content", "")[:120]
100
+ imp = r.get("importance", 0.0)
101
+ print(f" {i}. [{imp:.2f}] {content}")
102
+
103
+ elif cmd == "clear":
104
+ confirm = input("Clear scratchpad? This cannot be undone. [y/N]: ")
105
+ if confirm.lower() in ("y", "yes"):
106
+ beam.scratchpad_clear()
107
+ print("Scratchpad cleared.")
108
+ else:
109
+ print("Cancelled.")
110
+
111
+ elif cmd == "export":
112
+ output_path = getattr(args, "output", None)
113
+ if not output_path:
114
+ print("Usage: hermes mnemosyne export --output <path>")
115
+ return 1
116
+ try:
117
+ from mnemosyne.core.memory import Mnemosyne
118
+ mem = Mnemosyne(session_id="hermes_default")
119
+ result = mem.export_to_file(output_path)
120
+ print(f"Exported {result['working_memory_count']} working, {result['episodic_memory_count']} episodic, {result['legacy_memories_count']} legacy, {result['triples_count']} triples to {output_path}")
121
+ except Exception as e:
122
+ print(f"Export failed: {e}")
123
+ return 1
124
+
125
+ elif cmd == "import":
126
+ # --list-providers
127
+ if getattr(args, "list_providers", False):
128
+ from mnemosyne.core.importers import PROVIDERS
129
+ print("Supported import providers:")
130
+ for name, info in PROVIDERS.items():
131
+ print(f" {name}: {info['description']}")
132
+ print(f" docs: {info['docs']}")
133
+ print(f" env key: {info['env_key']}")
134
+ print(f" pip: {info['pypi_package']}")
135
+ return 0
136
+
137
+ # --agentic: generate instructions for user's AI agent
138
+ generate_script_flag = getattr(args, "generate_script", False)
139
+ agentic_flag = getattr(args, "agentic", False)
140
+ from_provider = getattr(args, "from_provider", None)
141
+ output_script = getattr(args, "output_script", None)
142
+
143
+ if agentic_flag and from_provider:
144
+ from mnemosyne.core.importers.agentic import generate_agent_instructions
145
+ instructions = generate_agent_instructions(from_provider)
146
+ if output_script:
147
+ Path(output_script).write_text(instructions)
148
+ print(f"Agent instructions saved to {output_script}")
149
+ else:
150
+ print(instructions)
151
+ return 0
152
+
153
+ if generate_script_flag and from_provider:
154
+ from mnemosyne.core.importers.agentic import generate_migration_script
155
+ api_key = getattr(args, "api_key", None)
156
+ user_id = getattr(args, "user_id", None)
157
+ script = generate_migration_script(
158
+ from_provider,
159
+ api_key=api_key or "",
160
+ user_id=user_id or "",
161
+ )
162
+ if output_script:
163
+ Path(output_script).write_text(script)
164
+ print(f"Migration script saved to {output_script}")
165
+ else:
166
+ print(script)
167
+ return 0
168
+
169
+ cross_provider = from_provider
170
+ input_path = getattr(args, "input", None)
171
+ dry_run = getattr(args, "dry_run", False)
172
+ session_id = getattr(args, "session_id", None)
173
+ channel_id = getattr(args, "channel_id", None)
174
+
175
+ try:
176
+ from mnemosyne.core.memory import Mnemosyne
177
+ mem = Mnemosyne(session_id=session_id or "import_session",
178
+ channel_id=channel_id)
179
+ except Exception as e:
180
+ print(f"Error: Mnemosyne not available: {e}")
181
+ return 1
182
+
183
+ # Cross-provider import
184
+ if cross_provider:
185
+ api_key = getattr(args, "api_key", None)
186
+ user_id = getattr(args, "user_id", None)
187
+ agent_id = getattr(args, "agent_id", None)
188
+ base_url = getattr(args, "base_url", None)
189
+
190
+ # Try env var fallback
191
+ import os
192
+ if not api_key:
193
+ info = __import__("mnemosyne.core.importers", fromlist=["PROVIDERS"]).PROVIDERS
194
+ pk = info.get(cross_provider, {}).get("env_key", "")
195
+ if pk:
196
+ api_key = os.environ.get(pk)
197
+ if not api_key:
198
+ print(f"Error: --api-key required for {cross_provider} import. "
199
+ f"Or set the {cross_provider.upper()}_API_KEY env var.")
200
+ return 1
201
+
202
+ print(f"Importing from {cross_provider}...")
203
+ if dry_run:
204
+ print(" (dry-run mode: no memories will be written)")
205
+
206
+ try:
207
+ from mnemosyne.core.importers import import_from_provider
208
+ result = import_from_provider(
209
+ cross_provider, mem,
210
+ api_key=api_key,
211
+ user_id=user_id,
212
+ agent_id=agent_id,
213
+ base_url=base_url,
214
+ dry_run=dry_run,
215
+ session_id=session_id,
216
+ channel_id=channel_id,
217
+ )
218
+ print(f"\nImport complete:")
219
+ print(f" Total found: {result.total}")
220
+ print(f" Imported: {result.imported}")
221
+ print(f" Skipped: {result.skipped}")
222
+ print(f" Failed: {result.failed}")
223
+ if result.errors:
224
+ print(f" Errors:")
225
+ for err in result.errors[:10]:
226
+ print(f" - {err}")
227
+ if len(result.errors) > 10:
228
+ print(f" ... and {len(result.errors) - 10} more")
229
+ return 0 if result.failed == 0 else 1
230
+ except ValueError as e:
231
+ print(f"Error: {e}")
232
+ return 1
233
+ except Exception as e:
234
+ print(f"Import failed: {e}")
235
+ return 1
236
+
237
+ # File import
238
+ force = getattr(args, "force", False)
239
+ if not input_path:
240
+ print("Usage: hermes mnemosyne import --input <path> [--force]")
241
+ print(" hermes mnemosyne import --from <provider> --api-key <key> [--dry-run]")
242
+ print(" hermes mnemosyne import --list-providers")
243
+ return 1
244
+ try:
245
+ stats = mem.import_from_file(input_path, force=force)
246
+ beam_stats = stats.get("beam", {})
247
+ legacy_stats = stats.get("legacy", {})
248
+ triples_stats = stats.get("triples", {})
249
+ print(f"Import complete:")
250
+ print(f" Working: +{beam_stats.get('working_memory', {}).get('inserted', 0)}")
251
+ print(f" Episodic: +{beam_stats.get('episodic_memory', {}).get('inserted', 0)}")
252
+ print(f" Legacy: +{legacy_stats.get('inserted', 0)}")
253
+ print(f" Triples: +{triples_stats.get('inserted', 0)}")
254
+ if force:
255
+ print(f" (force mode: overwrites applied)")
256
+ except Exception as e:
257
+ print(f"Import failed: {e}")
258
+ return 1
259
+
260
+ return 0
@@ -277,13 +277,42 @@ FORGET_SCHEMA = {
277
277
 
278
278
  IMPORT_SCHEMA = {
279
279
  "name": "mnemosyne_import",
280
- "description": "Import Mnemosyne memories from a JSON file. Idempotent by default.",
280
+ "description": "Import Mnemosyne memories from a JSON file or another memory provider (Mem0, etc.). Idempotent by default.",
281
281
  "parameters": {
282
282
  "type": "object",
283
283
  "properties": {
284
284
  "input_path": {
285
285
  "type": "string",
286
- "description": "File path to read the export JSON from"
286
+ "description": "File path to read the export JSON from (for file imports)"
287
+ },
288
+ "provider": {
289
+ "type": "string",
290
+ "description": "Provider to import from: 'mem0'. Requires api_key. Use --list-providers to see supported providers."
291
+ },
292
+ "api_key": {
293
+ "type": "string",
294
+ "description": "API key for the source provider (can also be set via env var: MEM0_API_KEY)"
295
+ },
296
+ "user_id": {
297
+ "type": "string",
298
+ "description": "Filter imported memories by user ID (provider-specific)"
299
+ },
300
+ "agent_id": {
301
+ "type": "string",
302
+ "description": "Filter imported memories by agent ID (provider-specific)"
303
+ },
304
+ "base_url": {
305
+ "type": "string",
306
+ "description": "Base URL for self-hosted provider instances"
307
+ },
308
+ "dry_run": {
309
+ "type": "boolean",
310
+ "description": "If true, validate and transform but don't write any memories",
311
+ "default": False
312
+ },
313
+ "channel_id": {
314
+ "type": "string",
315
+ "description": "Channel to assign imported memories to"
287
316
  },
288
317
  "force": {
289
318
  "type": "boolean",
@@ -291,7 +320,7 @@ IMPORT_SCHEMA = {
291
320
  "default": False
292
321
  }
293
322
  },
294
- "required": ["input_path"]
323
+ "required": []
295
324
  }
296
325
  }
297
326
 
@@ -538,14 +567,50 @@ def mnemosyne_forget(args: dict, **kwargs) -> str:
538
567
 
539
568
 
540
569
  def mnemosyne_import(args: dict, **kwargs) -> str:
541
- """Import memories from a JSON file"""
570
+ """Import memories from a JSON file or another memory provider."""
542
571
  try:
572
+ provider = args.get("provider", "").strip().lower()
543
573
  input_path = args.get("input_path", "").strip()
574
+ dry_run = args.get("dry_run", False)
575
+ channel_id = args.get("channel_id")
544
576
  force = args.get("force", False)
545
- if not input_path:
546
- return json.dumps({"error": "input_path is required"})
547
577
 
548
578
  mem = _get_memory()
579
+
580
+ # Cross-provider import
581
+ if provider:
582
+ api_key = args.get("api_key", "").strip()
583
+ user_id = args.get("user_id", "").strip() or None
584
+ agent_id = args.get("agent_id", "").strip() or None
585
+ base_url = args.get("base_url", "").strip() or None
586
+
587
+ if not api_key:
588
+ import os
589
+ env_key = f"{provider.upper()}_API_KEY"
590
+ api_key = os.environ.get(env_key, "")
591
+ if not api_key:
592
+ return json.dumps({
593
+ "error": f"api_key required for {provider} import. Set {provider.upper()}_API_KEY env var or pass api_key parameter."
594
+ })
595
+
596
+ from mnemosyne.core.importers import import_from_provider
597
+ result = import_from_provider(
598
+ provider, mem,
599
+ api_key=api_key,
600
+ user_id=user_id,
601
+ agent_id=agent_id,
602
+ base_url=base_url,
603
+ dry_run=dry_run,
604
+ channel_id=channel_id,
605
+ )
606
+ return json.dumps(result.to_dict())
607
+
608
+ # File import
609
+ if not input_path:
610
+ return json.dumps({
611
+ "error": "Either input_path (for file import) or provider (for cross-provider import) is required"
612
+ })
613
+
549
614
  stats = mem.import_from_file(input_path, force=force)
550
615
  return json.dumps({
551
616
  "status": "imported",
@@ -10,7 +10,7 @@ Example:
10
10
  >>> results = recall("user preferences")
11
11
  """
12
12
 
13
- __version__ = "2.1"
13
+ __version__ = "2.2"
14
14
  __author__ = "Abdias J"
15
15
  __license__ = "MIT"
16
16
 
@@ -0,0 +1,152 @@
1
+ """
2
+ Mnemosyne Cross-Provider Importers
3
+
4
+ Import memories from other AI memory providers into Mnemosyne.
5
+
6
+ Supported providers:
7
+ mem0 — Mem0 (cloud + self-hosted)
8
+ letta — Letta (formerly MemGPT)
9
+ zep — Zep enterprise memory
10
+ cognee — Cognee graph memory
11
+ honcho — Honcho entity memory
12
+ supermemory — SuperMemory cloud API
13
+
14
+ CLI usage:
15
+ hermes mnemosyne import --from mem0 --api-key sk-xxx
16
+ hermes mnemosyne import --file export.json --dry-run
17
+ hermes mnemosyne import --list-providers
18
+ hermes mnemosyne import --from mem0 --generate-script
19
+
20
+ Agentic migration:
21
+ hermes mnemosyne import --from zep --agentic
22
+ """
23
+
24
+ from .base import BaseImporter, ImporterResult, import_from_file
25
+ from .mem0 import Mem0Importer, import_from_mem0
26
+ from .letta import LettaImporter
27
+ from .zep import ZepImporter
28
+ from .cognee import CogneeImporter
29
+ from .honcho import HonchoImporter
30
+ from .supermemory import SuperMemoryImporter
31
+ from .agentic import (
32
+ AgenticImporter,
33
+ generate_migration_script,
34
+ generate_agent_instructions,
35
+ generate_docs_instructions,
36
+ )
37
+
38
+
39
+ # Registry of supported providers
40
+ PROVIDERS = {
41
+ "mem0": {
42
+ "name": "Mem0",
43
+ "class": Mem0Importer,
44
+ "module": "mem0",
45
+ "docs": "https://docs.mem0.ai",
46
+ "env_key": "MEM0_API_KEY",
47
+ "pypi_package": "mem0ai",
48
+ "description": "Memory platform with 24 vector store backends. Supports user/agent/app scoping.",
49
+ },
50
+ "letta": {
51
+ "name": "Letta (MemGPT)",
52
+ "class": LettaImporter,
53
+ "module": "letta",
54
+ "docs": "https://docs.letta.com",
55
+ "env_key": "LETTA_API_KEY",
56
+ "pypi_package": "letta-client",
57
+ "description": "Agent OS with hierarchical memory blocks. Export via .af AgentFile format.",
58
+ },
59
+ "zep": {
60
+ "name": "Zep",
61
+ "class": ZepImporter,
62
+ "module": "zep",
63
+ "docs": "https://docs.getzep.com",
64
+ "env_key": "ZEP_API_KEY",
65
+ "pypi_package": "zep-cloud",
66
+ "description": "Enterprise temporal knowledge graph. Session-based with user/thread model.",
67
+ },
68
+ "cognee": {
69
+ "name": "Cognee",
70
+ "class": CogneeImporter,
71
+ "module": "cognee",
72
+ "docs": "https://docs.cognee.ai",
73
+ "env_key": None,
74
+ "pypi_package": "cognee",
75
+ "description": "Graph-based memory with Kùzu + LanceDB + SQLite. Nodes/edges map to episodic/triples.",
76
+ },
77
+ "honcho": {
78
+ "name": "Honcho",
79
+ "class": HonchoImporter,
80
+ "module": "honcho",
81
+ "docs": "https://docs.honcho.dev",
82
+ "env_key": None,
83
+ "pypi_package": "honcho-ai",
84
+ "description": "Entity-centric memory by Plastic Labs. Workspace → Peer → Session → Message model.",
85
+ },
86
+ "supermemory": {
87
+ "name": "SuperMemory",
88
+ "class": SuperMemoryImporter,
89
+ "module": "supermemory",
90
+ "docs": "https://supermemory.ai/docs",
91
+ "env_key": "SUPERMEMORY_API_KEY",
92
+ "pypi_package": "supermemory",
93
+ "description": "Cloud memory API with container tags and document management.",
94
+ },
95
+ }
96
+
97
+
98
+ def list_providers() -> list:
99
+ """Return list of supported provider names."""
100
+ return list(PROVIDERS.keys())
101
+
102
+
103
+ def get_provider_info(name: str) -> dict:
104
+ """Get metadata for a supported provider."""
105
+ return PROVIDERS.get(name, {})
106
+
107
+
108
+ def import_from_provider(provider: str, mnemosyne, dry_run: bool = False,
109
+ session_id: str = None, channel_id: str = None,
110
+ **kwargs) -> ImporterResult:
111
+ """Import memories from a supported provider into Mnemosyne.
112
+
113
+ Args:
114
+ provider: Provider name (e.g., 'mem0', 'letta').
115
+ mnemosyne: Mnemosyne instance to import into.
116
+ dry_run: If True, validate and transform but don't write.
117
+ session_id: Override session for imported memories.
118
+ channel_id: Channel to assign imported memories to.
119
+ **kwargs: Provider-specific arguments (api_key, user_id, etc.)
120
+
121
+ Returns:
122
+ ImporterResult with import statistics.
123
+
124
+ Raises:
125
+ ValueError: If provider is not supported.
126
+ """
127
+ provider_info = PROVIDERS.get(provider)
128
+ if not provider_info:
129
+ supported = ", ".join(PROVIDERS.keys())
130
+ raise ValueError(
131
+ f"Unsupported provider: '{provider}'. Supported: {supported}"
132
+ )
133
+
134
+ importer_cls = provider_info["class"]
135
+ importer = importer_cls(**kwargs)
136
+ return importer.run(
137
+ mnemosyne,
138
+ dry_run=dry_run,
139
+ session_id=session_id,
140
+ channel_id=channel_id,
141
+ )
142
+
143
+
144
+ def generate_script(provider: str, **kwargs) -> str:
145
+ """Generate a migration script for the given provider."""
146
+ provider_info = PROVIDERS.get(provider)
147
+ if not provider_info:
148
+ supported = ", ".join(PROVIDERS.keys())
149
+ raise ValueError(
150
+ f"Unsupported provider: '{provider}'. Supported: {supported}"
151
+ )
152
+ return generate_migration_script(provider, **kwargs)