atmem 2.2.3__tar.gz → 2.2.4__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 (147) hide show
  1. {atmem-2.2.3/atmem.egg-info → atmem-2.2.4}/PKG-INFO +27 -12
  2. {atmem-2.2.3 → atmem-2.2.4}/README.md +25 -10
  3. {atmem-2.2.3 → atmem-2.2.4}/atmem/cli.py +42 -1
  4. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/atbot_service.py +1 -1
  5. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/compat.py +1 -1
  6. {atmem-2.2.3 → atmem-2.2.4}/atmem/dashboard_daemon.py +27 -0
  7. {atmem-2.2.3 → atmem-2.2.4}/atmem/mcp/server.py +1 -1
  8. {atmem-2.2.3 → atmem-2.2.4}/atmem/openclaw_install.py +27 -12
  9. {atmem-2.2.3 → atmem-2.2.4/atmem.egg-info}/PKG-INFO +27 -12
  10. {atmem-2.2.3 → atmem-2.2.4}/atmem.egg-info/SOURCES.txt +1 -0
  11. {atmem-2.2.3 → atmem-2.2.4}/atmem.egg-info/requires.txt +1 -1
  12. {atmem-2.2.3 → atmem-2.2.4}/docs/atbot-release.md +1 -1
  13. {atmem-2.2.3 → atmem-2.2.4}/docs/capabilities.json +2 -2
  14. {atmem-2.2.3 → atmem-2.2.4}/docs/current-status.md +15 -7
  15. {atmem-2.2.3 → atmem-2.2.4}/docs/openclaw-setup.md +11 -3
  16. atmem-2.2.4/docs/releases/v2.2.4.md +53 -0
  17. {atmem-2.2.3 → atmem-2.2.4}/integrations/openclaw/README.md +2 -2
  18. {atmem-2.2.3 → atmem-2.2.4}/integrations/openclaw/openclaw.plugin.json +3 -2
  19. {atmem-2.2.3 → atmem-2.2.4}/integrations/openclaw/package-lock.json +2936 -1886
  20. {atmem-2.2.3 → atmem-2.2.4}/integrations/openclaw/package.json +6 -2
  21. {atmem-2.2.3 → atmem-2.2.4}/integrations/openclaw/src/rpc-client.ts +1 -1
  22. {atmem-2.2.3 → atmem-2.2.4}/pyproject.toml +2 -2
  23. {atmem-2.2.3 → atmem-2.2.4}/tests/test_cli_guidance.py +13 -2
  24. {atmem-2.2.3 → atmem-2.2.4}/tests/test_control_plane.py +3 -3
  25. {atmem-2.2.3 → atmem-2.2.4}/tests/test_control_verify.py +1 -0
  26. {atmem-2.2.3 → atmem-2.2.4}/tests/test_dashboard_daemon.py +50 -1
  27. {atmem-2.2.3 → atmem-2.2.4}/tests/test_documentation.py +5 -5
  28. {atmem-2.2.3 → atmem-2.2.4}/tests/test_openclaw_install.py +30 -4
  29. {atmem-2.2.3 → atmem-2.2.4}/tools/smoke_installed_package.py +2 -2
  30. {atmem-2.2.3 → atmem-2.2.4}/tools/smoke_upgrade_from_2_1.py +6 -6
  31. {atmem-2.2.3 → atmem-2.2.4}/LICENSE +0 -0
  32. {atmem-2.2.3 → atmem-2.2.4}/MANIFEST.in +0 -0
  33. {atmem-2.2.3 → atmem-2.2.4}/atmem/__init__.py +0 -0
  34. {atmem-2.2.3 → atmem-2.2.4}/atmem/adapters/__init__.py +0 -0
  35. {atmem-2.2.3 → atmem-2.2.4}/atmem/adapters/base.py +0 -0
  36. {atmem-2.2.3 → atmem-2.2.4}/atmem/adapters/langgraph.py +0 -0
  37. {atmem-2.2.3 → atmem-2.2.4}/atmem/adapters/pydantic_ai.py +0 -0
  38. {atmem-2.2.3 → atmem-2.2.4}/atmem/contracts/__init__.py +0 -0
  39. {atmem-2.2.3 → atmem-2.2.4}/atmem/contracts/models.py +0 -0
  40. {atmem-2.2.3 → atmem-2.2.4}/atmem/contracts/versions.py +0 -0
  41. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/__init__.py +0 -0
  42. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/assets/app.css +0 -0
  43. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/assets/app.html +0 -0
  44. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/assets/app.js +0 -0
  45. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/assets/atmem.jpg +0 -0
  46. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/atbot_companion.py +0 -0
  47. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/blackbox.py +0 -0
  48. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/evidence.py +0 -0
  49. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/hosts.py +0 -0
  50. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/manager.py +0 -0
  51. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/models.py +0 -0
  52. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/openclaw_native.py +0 -0
  53. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/openclaw_topology.py +0 -0
  54. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/server.py +0 -0
  55. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/state.py +0 -0
  56. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/store.py +0 -0
  57. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/topology.py +0 -0
  58. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/ui.py +0 -0
  59. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/verify.py +0 -0
  60. {atmem-2.2.3 → atmem-2.2.4}/atmem/control/web.py +0 -0
  61. {atmem-2.2.3 → atmem-2.2.4}/atmem/core/__init__.py +0 -0
  62. {atmem-2.2.3 → atmem-2.2.4}/atmem/core/canonical.py +0 -0
  63. {atmem-2.2.3 → atmem-2.2.4}/atmem/core/fact_keys.py +0 -0
  64. {atmem-2.2.3 → atmem-2.2.4}/atmem/core/keys.py +0 -0
  65. {atmem-2.2.3 → atmem-2.2.4}/atmem/core/policy.py +0 -0
  66. {atmem-2.2.3 → atmem-2.2.4}/atmem/core/storage.py +0 -0
  67. {atmem-2.2.3 → atmem-2.2.4}/atmem/extract/__init__.py +0 -0
  68. {atmem-2.2.3 → atmem-2.2.4}/atmem/extract/rules.py +0 -0
  69. {atmem-2.2.3 → atmem-2.2.4}/atmem/graph.py +0 -0
  70. {atmem-2.2.3 → atmem-2.2.4}/atmem/investigate.py +0 -0
  71. {atmem-2.2.3 → atmem-2.2.4}/atmem/maintenance.py +0 -0
  72. {atmem-2.2.3 → atmem-2.2.4}/atmem/mcp/__init__.py +0 -0
  73. {atmem-2.2.3 → atmem-2.2.4}/atmem/media.py +0 -0
  74. {atmem-2.2.3 → atmem-2.2.4}/atmem/memory.py +0 -0
  75. {atmem-2.2.3 → atmem-2.2.4}/atmem/retrieve/__init__.py +0 -0
  76. {atmem-2.2.3 → atmem-2.2.4}/atmem/retrieve/rank.py +0 -0
  77. {atmem-2.2.3 → atmem-2.2.4}/atmem/schemas/__init__.py +0 -0
  78. {atmem-2.2.3 → atmem-2.2.4}/atmem/schemas/v1/capabilities.json +0 -0
  79. {atmem-2.2.3 → atmem-2.2.4}/atmem/schemas/v1/context-package.json +0 -0
  80. {atmem-2.2.3 → atmem-2.2.4}/atmem/schemas/v1/memory-proposal.json +0 -0
  81. {atmem-2.2.3 → atmem-2.2.4}/atmem/schemas/v1/recall-request.json +0 -0
  82. {atmem-2.2.3 → atmem-2.2.4}/atmem/schemas/v1/scope.json +0 -0
  83. {atmem-2.2.3 → atmem-2.2.4}/atmem/schemas/v1/source-capture.json +0 -0
  84. {atmem-2.2.3 → atmem-2.2.4}/atmem/semantic/__init__.py +0 -0
  85. {atmem-2.2.3 → atmem-2.2.4}/atmem/semantic/index.py +0 -0
  86. {atmem-2.2.3 → atmem-2.2.4}/atmem/semantic/providers.py +0 -0
  87. {atmem-2.2.3 → atmem-2.2.4}/atmem/store/__init__.py +0 -0
  88. {atmem-2.2.3 → atmem-2.2.4}/atmem/store/sqlite.py +0 -0
  89. {atmem-2.2.3 → atmem-2.2.4}/atmem.egg-info/dependency_links.txt +0 -0
  90. {atmem-2.2.3 → atmem-2.2.4}/atmem.egg-info/entry_points.txt +0 -0
  91. {atmem-2.2.3 → atmem-2.2.4}/atmem.egg-info/top_level.txt +0 -0
  92. {atmem-2.2.3 → atmem-2.2.4}/docs/agent-blackbox.md +0 -0
  93. {atmem-2.2.3 → atmem-2.2.4}/docs/audit-log-spec.md +0 -0
  94. {atmem-2.2.3 → atmem-2.2.4}/docs/audit-search.md +0 -0
  95. {atmem-2.2.3 → atmem-2.2.4}/docs/auditing-guide.md +0 -0
  96. {atmem-2.2.3 → atmem-2.2.4}/docs/control-plane.md +0 -0
  97. {atmem-2.2.3 → atmem-2.2.4}/docs/dashboard-design-language.md +0 -0
  98. {atmem-2.2.3 → atmem-2.2.4}/docs/data-storage-and-backup.md +0 -0
  99. {atmem-2.2.3 → atmem-2.2.4}/docs/framework-adapters.md +0 -0
  100. {atmem-2.2.3 → atmem-2.2.4}/docs/generic-adapter.md +0 -0
  101. {atmem-2.2.3 → atmem-2.2.4}/docs/integration-guide.md +0 -0
  102. {atmem-2.2.3 → atmem-2.2.4}/docs/multimodal-observations.md +0 -0
  103. {atmem-2.2.3 → atmem-2.2.4}/docs/releases/v1.0.0.md +0 -0
  104. {atmem-2.2.3 → atmem-2.2.4}/docs/releases/v2.0.0.md +0 -0
  105. {atmem-2.2.3 → atmem-2.2.4}/docs/releases/v2.0.1.md +0 -0
  106. {atmem-2.2.3 → atmem-2.2.4}/docs/releases/v2.1.0.md +0 -0
  107. {atmem-2.2.3 → atmem-2.2.4}/docs/releases/v2.2.0.md +0 -0
  108. {atmem-2.2.3 → atmem-2.2.4}/docs/releases/v2.2.1.md +0 -0
  109. {atmem-2.2.3 → atmem-2.2.4}/docs/releases/v2.2.2.md +0 -0
  110. {atmem-2.2.3 → atmem-2.2.4}/docs/releases/v2.2.3.md +0 -0
  111. {atmem-2.2.3 → atmem-2.2.4}/docs/saas-integration.md +0 -0
  112. {atmem-2.2.3 → atmem-2.2.4}/docs/semantic-search.md +0 -0
  113. {atmem-2.2.3 → atmem-2.2.4}/integrations/openclaw/index.ts +0 -0
  114. {atmem-2.2.3 → atmem-2.2.4}/integrations/openclaw/src/setup.ts +0 -0
  115. {atmem-2.2.3 → atmem-2.2.4}/integrations/openclaw/src/types.ts +0 -0
  116. {atmem-2.2.3 → atmem-2.2.4}/integrations/openclaw/test/hooks.mjs +0 -0
  117. {atmem-2.2.3 → atmem-2.2.4}/integrations/openclaw/test/setup.mjs +0 -0
  118. {atmem-2.2.3 → atmem-2.2.4}/integrations/openclaw/test/smoke.mjs +0 -0
  119. {atmem-2.2.3 → atmem-2.2.4}/integrations/openclaw/tsconfig.json +0 -0
  120. {atmem-2.2.3 → atmem-2.2.4}/setup.cfg +0 -0
  121. {atmem-2.2.3 → atmem-2.2.4}/tests/test_atbot_companion.py +0 -0
  122. {atmem-2.2.3 → atmem-2.2.4}/tests/test_atbot_service.py +0 -0
  123. {atmem-2.2.3 → atmem-2.2.4}/tests/test_auditability.py +0 -0
  124. {atmem-2.2.3 → atmem-2.2.4}/tests/test_blackbox.py +0 -0
  125. {atmem-2.2.3 → atmem-2.2.4}/tests/test_cli.py +0 -0
  126. {atmem-2.2.3 → atmem-2.2.4}/tests/test_contracts_v1.py +0 -0
  127. {atmem-2.2.3 → atmem-2.2.4}/tests/test_control_evidence.py +0 -0
  128. {atmem-2.2.3 → atmem-2.2.4}/tests/test_encryption.py +0 -0
  129. {atmem-2.2.3 → atmem-2.2.4}/tests/test_extract.py +0 -0
  130. {atmem-2.2.3 → atmem-2.2.4}/tests/test_framework_adapters.py +0 -0
  131. {atmem-2.2.3 → atmem-2.2.4}/tests/test_generic_control.py +0 -0
  132. {atmem-2.2.3 → atmem-2.2.4}/tests/test_graph.py +0 -0
  133. {atmem-2.2.3 → atmem-2.2.4}/tests/test_host_adapter.py +0 -0
  134. {atmem-2.2.3 → atmem-2.2.4}/tests/test_layers.py +0 -0
  135. {atmem-2.2.3 → atmem-2.2.4}/tests/test_maintenance.py +0 -0
  136. {atmem-2.2.3 → atmem-2.2.4}/tests/test_mcp.py +0 -0
  137. {atmem-2.2.3 → atmem-2.2.4}/tests/test_media_observations.py +0 -0
  138. {atmem-2.2.3 → atmem-2.2.4}/tests/test_memory.py +0 -0
  139. {atmem-2.2.3 → atmem-2.2.4}/tests/test_openclaw_control.py +0 -0
  140. {atmem-2.2.3 → atmem-2.2.4}/tests/test_openclaw_topology.py +0 -0
  141. {atmem-2.2.3 → atmem-2.2.4}/tests/test_policy.py +0 -0
  142. {atmem-2.2.3 → atmem-2.2.4}/tests/test_recall_evidence.py +0 -0
  143. {atmem-2.2.3 → atmem-2.2.4}/tests/test_restore_receipt.py +0 -0
  144. {atmem-2.2.3 → atmem-2.2.4}/tests/test_retrieve.py +0 -0
  145. {atmem-2.2.3 → atmem-2.2.4}/tests/test_semantic_search.py +0 -0
  146. {atmem-2.2.3 → atmem-2.2.4}/tests/test_store_transactions.py +0 -0
  147. {atmem-2.2.3 → atmem-2.2.4}/tools/verify_audit.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atmem
3
- Version: 2.2.3
3
+ Version: 2.2.4
4
4
  Summary: Host-neutral Agent Black Box and reversible memory control plane.
5
5
  Author-email: aetna000 <aetna000@gmail.com>
6
6
  Maintainer-email: aetna000 <aetna000@gmail.com>
@@ -24,7 +24,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
24
  Requires-Python: >=3.10
25
25
  Description-Content-Type: text/markdown
26
26
  License-File: LICENSE
27
- Requires-Dist: atmem-atbot==0.1.0a2
27
+ Requires-Dist: atmem-atbot==0.1.0a3
28
28
  Provides-Extra: dev
29
29
  Requires-Dist: pytest>=8.0.0; extra == "dev"
30
30
  Requires-Dist: tomli>=2.0; python_version < "3.11" and extra == "dev"
@@ -44,7 +44,7 @@ Dynamic: license-file
44
44
 
45
45
  # AtMem
46
46
 
47
- [![Version 2.2.3](https://img.shields.io/badge/version-2.2.3-blue)](./docs/releases/v2.2.3.md)
47
+ [![Version 2.2.4](https://img.shields.io/badge/version-2.2.4-blue)](./docs/releases/v2.2.4.md)
48
48
  [![CI](https://github.com/aetna000/atmem/actions/workflows/ci.yml/badge.svg)](https://github.com/aetna000/atmem/actions/workflows/ci.yml)
49
49
 
50
50
  **AtMem is a host-neutral Agent Black Box and reversible memory control plane.**
@@ -59,7 +59,7 @@ authorizes, stores, scopes, injects, corrects, and deletes memory.
59
59
  ### 1. Install AtMem and choose memory intelligence
60
60
 
61
61
  ```bash
62
- python -m pip install --upgrade atmem==2.2.3
62
+ python -m pip install --upgrade atmem==2.2.4
63
63
  atmem atbot setup
64
64
  atmem atbot doctor
65
65
  atmem dashboard
@@ -87,15 +87,30 @@ connection. Do not install the npm package yourself.
87
87
  Already using AtMem 2.1 with OpenClaw? Upgrade in place:
88
88
 
89
89
  ```bash
90
- python -m pip install --upgrade atmem==2.2.3
90
+ python -m pip install --upgrade atmem==2.2.4
91
91
  atmem openclaw upgrade
92
92
  atmem control verify
93
93
  ```
94
94
 
95
+ The upgrade command is idempotent. It replaces a running dashboard with the
96
+ new Python runtime before refreshing and testing the OpenClaw bridge, so the UI
97
+ cannot continue serving the pre-upgrade package version.
98
+
99
+ For Pydantic AI, LangGraph, or another non-OpenClaw integration, finish an
100
+ upgrade by restarting a background dashboard directly:
101
+
102
+ ```bash
103
+ python -m pip install --upgrade atmem
104
+ atmem dashboard daemon restart
105
+ ```
106
+
107
+ Using `python -m pip` is important: it upgrades the same Python environment
108
+ selected by `python`, rather than an unrelated `pip` executable on `PATH`.
109
+
95
110
  #### Pydantic AI — native capability
96
111
 
97
112
  ```bash
98
- python -m pip install 'atmem[pydantic-ai]==2.2.3'
113
+ python -m pip install 'atmem[pydantic-ai]==2.2.4'
99
114
  atmem control shadow --host generic --memory-db ~/.atmem/memories.db
100
115
  ```
101
116
 
@@ -119,7 +134,7 @@ agent = Agent("openai:gpt-5-mini", capabilities=[memory])
119
134
  #### LangChain/LangGraph — native middleware
120
135
 
121
136
  ```bash
122
- python -m pip install 'atmem[langgraph]==2.2.3'
137
+ python -m pip install 'atmem[langgraph]==2.2.4'
123
138
  atmem control shadow --host generic --memory-db ~/.atmem/memories.db
124
139
  ```
125
140
 
@@ -163,7 +178,7 @@ If AtBot or its selected model is unavailable, AtMem continues with safe local
163
178
  capture and hybrid ranking. Memory authority and agent operation do not depend
164
179
  on a hosted model.
165
180
 
166
- > **Release status:** this repository describes **AtMem 2.2.3**. AtBot is a
181
+ > **Release status:** this repository describes **AtMem 2.2.4**. AtBot is a
167
182
  > separately packaged, headless component installed and managed by AtMem; it is
168
183
  > not an independent agent or a second memory authority.
169
184
 
@@ -182,7 +197,7 @@ and restores it exactly.
182
197
  ## Installation details
183
198
 
184
199
  ```bash
185
- python -m pip install atmem==2.2.3
200
+ python -m pip install atmem==2.2.4
186
201
  atmem --version
187
202
  ```
188
203
 
@@ -190,7 +205,7 @@ AtMem requires Python 3.10 or newer. It always creates a dependency-free local
190
205
  vector sidecar; the semantic extra adds an optional local embedding upgrade:
191
206
 
192
207
  ```bash
193
- python -m pip install 'atmem[semantic]==2.2.3'
208
+ python -m pip install 'atmem[semantic]==2.2.4'
194
209
  ```
195
210
 
196
211
  For repository development, install both workspace packages:
@@ -370,7 +385,7 @@ atmem control restore
370
385
  Existing 2.1 installations upgrade without starting a new migration:
371
386
 
372
387
  ```bash
373
- python -m pip install --upgrade atmem==2.2.3
388
+ python -m pip install --upgrade atmem==2.2.4
374
389
  atmem openclaw upgrade
375
390
  atmem control verify
376
391
  ```
@@ -516,7 +531,7 @@ npm test
516
531
  npm run smoke
517
532
  ```
518
533
 
519
- Current repository metadata is version **2.2.3**. Python and npm release
534
+ Current repository metadata is version **2.2.4**. Python and npm release
520
535
  versions are intentionally kept equal because the OpenClaw installer pins the
521
536
  matching bridge.
522
537
 
@@ -1,6 +1,6 @@
1
1
  # AtMem
2
2
 
3
- [![Version 2.2.3](https://img.shields.io/badge/version-2.2.3-blue)](./docs/releases/v2.2.3.md)
3
+ [![Version 2.2.4](https://img.shields.io/badge/version-2.2.4-blue)](./docs/releases/v2.2.4.md)
4
4
  [![CI](https://github.com/aetna000/atmem/actions/workflows/ci.yml/badge.svg)](https://github.com/aetna000/atmem/actions/workflows/ci.yml)
5
5
 
6
6
  **AtMem is a host-neutral Agent Black Box and reversible memory control plane.**
@@ -15,7 +15,7 @@ authorizes, stores, scopes, injects, corrects, and deletes memory.
15
15
  ### 1. Install AtMem and choose memory intelligence
16
16
 
17
17
  ```bash
18
- python -m pip install --upgrade atmem==2.2.3
18
+ python -m pip install --upgrade atmem==2.2.4
19
19
  atmem atbot setup
20
20
  atmem atbot doctor
21
21
  atmem dashboard
@@ -43,15 +43,30 @@ connection. Do not install the npm package yourself.
43
43
  Already using AtMem 2.1 with OpenClaw? Upgrade in place:
44
44
 
45
45
  ```bash
46
- python -m pip install --upgrade atmem==2.2.3
46
+ python -m pip install --upgrade atmem==2.2.4
47
47
  atmem openclaw upgrade
48
48
  atmem control verify
49
49
  ```
50
50
 
51
+ The upgrade command is idempotent. It replaces a running dashboard with the
52
+ new Python runtime before refreshing and testing the OpenClaw bridge, so the UI
53
+ cannot continue serving the pre-upgrade package version.
54
+
55
+ For Pydantic AI, LangGraph, or another non-OpenClaw integration, finish an
56
+ upgrade by restarting a background dashboard directly:
57
+
58
+ ```bash
59
+ python -m pip install --upgrade atmem
60
+ atmem dashboard daemon restart
61
+ ```
62
+
63
+ Using `python -m pip` is important: it upgrades the same Python environment
64
+ selected by `python`, rather than an unrelated `pip` executable on `PATH`.
65
+
51
66
  #### Pydantic AI — native capability
52
67
 
53
68
  ```bash
54
- python -m pip install 'atmem[pydantic-ai]==2.2.3'
69
+ python -m pip install 'atmem[pydantic-ai]==2.2.4'
55
70
  atmem control shadow --host generic --memory-db ~/.atmem/memories.db
56
71
  ```
57
72
 
@@ -75,7 +90,7 @@ agent = Agent("openai:gpt-5-mini", capabilities=[memory])
75
90
  #### LangChain/LangGraph — native middleware
76
91
 
77
92
  ```bash
78
- python -m pip install 'atmem[langgraph]==2.2.3'
93
+ python -m pip install 'atmem[langgraph]==2.2.4'
79
94
  atmem control shadow --host generic --memory-db ~/.atmem/memories.db
80
95
  ```
81
96
 
@@ -119,7 +134,7 @@ If AtBot or its selected model is unavailable, AtMem continues with safe local
119
134
  capture and hybrid ranking. Memory authority and agent operation do not depend
120
135
  on a hosted model.
121
136
 
122
- > **Release status:** this repository describes **AtMem 2.2.3**. AtBot is a
137
+ > **Release status:** this repository describes **AtMem 2.2.4**. AtBot is a
123
138
  > separately packaged, headless component installed and managed by AtMem; it is
124
139
  > not an independent agent or a second memory authority.
125
140
 
@@ -138,7 +153,7 @@ and restores it exactly.
138
153
  ## Installation details
139
154
 
140
155
  ```bash
141
- python -m pip install atmem==2.2.3
156
+ python -m pip install atmem==2.2.4
142
157
  atmem --version
143
158
  ```
144
159
 
@@ -146,7 +161,7 @@ AtMem requires Python 3.10 or newer. It always creates a dependency-free local
146
161
  vector sidecar; the semantic extra adds an optional local embedding upgrade:
147
162
 
148
163
  ```bash
149
- python -m pip install 'atmem[semantic]==2.2.3'
164
+ python -m pip install 'atmem[semantic]==2.2.4'
150
165
  ```
151
166
 
152
167
  For repository development, install both workspace packages:
@@ -326,7 +341,7 @@ atmem control restore
326
341
  Existing 2.1 installations upgrade without starting a new migration:
327
342
 
328
343
  ```bash
329
- python -m pip install --upgrade atmem==2.2.3
344
+ python -m pip install --upgrade atmem==2.2.4
330
345
  atmem openclaw upgrade
331
346
  atmem control verify
332
347
  ```
@@ -472,7 +487,7 @@ npm test
472
487
  npm run smoke
473
488
  ```
474
489
 
475
- Current repository metadata is version **2.2.3**. Python and npm release
490
+ Current repository metadata is version **2.2.4**. Python and npm release
476
491
  versions are intentionally kept equal because the OpenClaw installer pins the
477
492
  matching bridge.
478
493
 
@@ -79,7 +79,10 @@ Run `atmem COMMAND --help` for command-specific examples.""",
79
79
  )
80
80
  openclaw_upgrade = openclaw_commands.add_parser(
81
81
  "upgrade",
82
- help="Upgrade and verify the bridge without changing the current memory mode",
82
+ help=(
83
+ "Restart a running dashboard, upgrade the bridge, and verify the current "
84
+ "memory mode"
85
+ ),
83
86
  )
84
87
  openclaw_upgrade.add_argument(
85
88
  "--state",
@@ -1077,6 +1080,33 @@ def _print(value: object) -> None:
1077
1080
  print(json.dumps(value, indent=2, sort_keys=True))
1078
1081
 
1079
1082
 
1083
+ def _restart_running_dashboard_after_upgrade() -> dict[str, object]:
1084
+ """Replace a live pre-upgrade dashboard with this CLI's runtime."""
1085
+
1086
+ from atmem.dashboard_daemon import manage_dashboard_daemon
1087
+
1088
+ current = manage_dashboard_daemon("status")
1089
+ if not current.get("running"):
1090
+ return {
1091
+ "format": "atmem-dashboard-upgrade-v1",
1092
+ "was_running": False,
1093
+ "restarted": False,
1094
+ }
1095
+ restarted = manage_dashboard_daemon("restart")
1096
+ if not restarted.get("running"):
1097
+ raise ValueError(
1098
+ "the dashboard was running before upgrade but did not restart; "
1099
+ "run `atmem dashboard daemon restart`"
1100
+ )
1101
+ return {
1102
+ "format": "atmem-dashboard-upgrade-v1",
1103
+ "was_running": True,
1104
+ "restarted": True,
1105
+ "atmem_version": restarted.get("atmem_version"),
1106
+ "url": restarted.get("url"),
1107
+ }
1108
+
1109
+
1080
1110
  def _run_openclaw(args: argparse.Namespace) -> None:
1081
1111
  if args.openclaw_command == "memory":
1082
1112
  from atmem.control import ControlPlaneManager
@@ -1117,6 +1147,7 @@ def _run_openclaw(args: argparse.Namespace) -> None:
1117
1147
  from atmem.openclaw_install import refresh_openclaw_bridge_and_test
1118
1148
 
1119
1149
  try:
1150
+ dashboard = _restart_running_dashboard_after_upgrade()
1120
1151
  result = refresh_openclaw_bridge_and_test(
1121
1152
  state_path=args.state or DEFAULT_STATE_PATH
1122
1153
  )
@@ -1133,6 +1164,7 @@ def _run_openclaw(args: argparse.Namespace) -> None:
1133
1164
  print("AtMem OpenClaw upgrade did not complete", file=sys.stderr)
1134
1165
  print(f"\n{exc}", file=sys.stderr)
1135
1166
  raise SystemExit(1) from None
1167
+ result["dashboard"] = dashboard
1136
1168
  if args.json:
1137
1169
  _print(result)
1138
1170
  else:
@@ -1144,6 +1176,10 @@ def _run_openclaw(args: argparse.Namespace) -> None:
1144
1176
  print(f" Current bridge {result['bridge_version']}")
1145
1177
  print(f" Memory mode {result['mode']}")
1146
1178
  print(f" Test flight {result['test_flight']['verdict']}")
1179
+ print(
1180
+ " Dashboard "
1181
+ + ("restarted" if dashboard["restarted"] else "was not running")
1182
+ )
1147
1183
  return
1148
1184
  if args.openclaw_command != "install":
1149
1185
  raise ValueError(f"unknown OpenClaw command: {args.openclaw_command}")
@@ -1907,6 +1943,11 @@ def _run_dashboard(args: argparse.Namespace) -> None:
1907
1943
  print(f" Dashboard {result['url']}")
1908
1944
  if result.get("log_path"):
1909
1945
  print(f" Log {result['log_path']}")
1946
+ if result.get("restart_required"):
1947
+ print(
1948
+ " Action This dashboard uses an older AtMem runtime or "
1949
+ "Python environment. Run `atmem dashboard daemon restart`."
1950
+ )
1910
1951
  if result.get("opened"):
1911
1952
  print("\nOpened the dashboard in the default browser.")
1912
1953
  if result.get("removed"):
@@ -16,7 +16,7 @@ from typing import Any
16
16
  from urllib.parse import urlparse
17
17
 
18
18
 
19
- PINNED_ATBOT_VERSION = "0.1.0a2"
19
+ PINNED_ATBOT_VERSION = "0.1.0a3"
20
20
  ATBOT_DISTRIBUTION = "atmem-atbot"
21
21
  ATBOT_PROTOCOL_VERSION = "1"
22
22
  DEFAULT_ROOT = Path.home() / ".atmem" / "atbot"
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import re
4
4
 
5
5
 
6
- TESTED_OPENCLAW_VERSIONS = ("2026.7.1-2",)
6
+ TESTED_OPENCLAW_VERSIONS = ("2026.7.1-2", "2026.8.1")
7
7
 
8
8
  _VERSION_RE = re.compile(r"(?<!\d)(\d{4})\.(\d+)\.(\d+)(?:-(\d+))?(?!\d)")
9
9
 
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from importlib.metadata import PackageNotFoundError, version
3
4
  import json
4
5
  import os
5
6
  from pathlib import Path
@@ -105,6 +106,7 @@ def _start(
105
106
  log_offset = log_path.stat().st_size if log_path.exists() else 0
106
107
  command = [
107
108
  sys.executable,
109
+ "-I",
108
110
  "-m",
109
111
  "atmem.cli",
110
112
  "dashboard",
@@ -136,6 +138,8 @@ def _start(
136
138
  ),
137
139
  "log_path": str(log_path),
138
140
  "started_at": utc_now(),
141
+ "python_executable": str(Path(sys.executable).expanduser().absolute()),
142
+ "atmem_version": _installed_atmem_version(),
139
143
  }
140
144
  _write(state_path, value)
141
145
  deadline = time.monotonic() + 5.0
@@ -198,9 +202,32 @@ def _status(state_path: Path) -> dict[str, Any]:
198
202
  pid = int(value.get("pid") or 0)
199
203
  value["installed"] = True
200
204
  value["running"] = pid > 0 and _alive(pid)
205
+ current_version = _installed_atmem_version()
206
+ value["current_atmem_version"] = current_version
207
+ current_executable = str(Path(sys.executable).expanduser().absolute())
208
+ value["current_python_executable"] = current_executable
209
+ recorded_version = value.get("atmem_version")
210
+ recorded_executable = value.get("python_executable")
211
+ value["restart_required"] = bool(
212
+ value["running"]
213
+ and (
214
+ (recorded_version is not None and recorded_version != current_version)
215
+ or (
216
+ recorded_executable is not None
217
+ and recorded_executable != current_executable
218
+ )
219
+ )
220
+ )
201
221
  return value
202
222
 
203
223
 
224
+ def _installed_atmem_version() -> str:
225
+ try:
226
+ return version("atmem")
227
+ except PackageNotFoundError:
228
+ return "development"
229
+
230
+
204
231
  def _alive(pid: int) -> bool:
205
232
  try:
206
233
  os.kill(pid, 0)
@@ -26,7 +26,7 @@ try:
26
26
 
27
27
  SERVER_VERSION = _pkg_version("atmem")
28
28
  except Exception: # not installed (e.g. run from a checkout)
29
- SERVER_VERSION = "2.2.3"
29
+ SERVER_VERSION = "2.2.4"
30
30
 
31
31
  _SUBJECT_PROPERTY = {
32
32
  "subject_id": {
@@ -4,6 +4,7 @@ from dataclasses import dataclass
4
4
  import json
5
5
  import os
6
6
  from pathlib import Path
7
+ import re
7
8
  import shutil
8
9
  import subprocess
9
10
  import time
@@ -16,7 +17,7 @@ from atmem.control.manager import DEFAULT_STATE_PATH, DEFAULT_CONTROL_ROOT
16
17
 
17
18
  OPENCLAW_PLUGIN_ID = "memory-atmem"
18
19
  OPENCLAW_PLUGIN_PACKAGE = "openclaw-memory-atmem"
19
- OPENCLAW_PLUGIN_VERSION = "2.2.3"
20
+ OPENCLAW_PLUGIN_VERSION = "2.2.4"
20
21
  _CONFIG_KEY = "plugins.entries.memory-atmem"
21
22
 
22
23
 
@@ -58,7 +59,9 @@ def install_openclaw(
58
59
  )
59
60
 
60
61
  engine_version = _verify_engine(engine, run)
61
- _require_success(run([openclaw, "--version"]), "OpenClaw version check")
62
+ openclaw_version = run([openclaw, "--version"])
63
+ _require_success(openclaw_version, "OpenClaw version check")
64
+ capability_consent = _capability_consent_arguments(openclaw_version.stdout)
62
65
 
63
66
  report(2, total_steps, "Reading the current OpenClaw configuration")
64
67
  prior_plugin = _inspect_plugin(openclaw, run, optional=True)
@@ -81,8 +84,12 @@ def install_openclaw(
81
84
  f"npm:{OPENCLAW_PLUGIN_PACKAGE}@{OPENCLAW_PLUGIN_VERSION}",
82
85
  "--pin",
83
86
  ]
84
- if prior_version is not None:
87
+ # OpenClaw 2.0 treats third-party npm plugins as reviewed-but-
88
+ # untrusted sources. The operator already chose AtMem's managed
89
+ # installer, so confirm that exact pinned artifact explicitly.
90
+ if prior_version is not None or capability_consent:
85
91
  install_command.append("--force")
92
+ install_command.extend(capability_consent)
86
93
  _require_success(run(install_command), "OpenClaw bridge installation")
87
94
  package_changed = True
88
95
 
@@ -237,6 +244,7 @@ def install_openclaw(
237
244
  f"npm:{OPENCLAW_PLUGIN_PACKAGE}@{prior_version}",
238
245
  "--pin",
239
246
  "--force",
247
+ *capability_consent,
240
248
  ]
241
249
  ),
242
250
  "bridge package restore",
@@ -277,19 +285,13 @@ def refresh_openclaw_bridge_and_test(
277
285
  openclaw = shutil.which("openclaw")
278
286
  if openclaw is None:
279
287
  raise ValueError("OpenClaw was not found on PATH")
288
+ openclaw_version = run([openclaw, "--version"])
289
+ _require_success(openclaw_version, "OpenClaw version check")
290
+ capability_consent = _capability_consent_arguments(openclaw_version.stdout)
280
291
  installed_before = _inspect_plugin(openclaw, run, optional=False)
281
292
  prior_version = _find_plugin_version(installed_before)
282
293
  runtime_before = _inspect_plugin(openclaw, run, optional=True, runtime=True)
283
294
  runtime_version = _find_plugin_version(runtime_before)
284
- if (
285
- prior_version == OPENCLAW_PLUGIN_VERSION
286
- and runtime_version == OPENCLAW_PLUGIN_VERSION
287
- ):
288
- raise ValueError(
289
- f"bridge {OPENCLAW_PLUGIN_VERSION} is already loaded; the installed "
290
- "AtMem package does not yet pin a newer bridge"
291
- )
292
-
293
295
  package_changed = prior_version != OPENCLAW_PLUGIN_VERSION
294
296
  try:
295
297
  if package_changed:
@@ -302,6 +304,7 @@ def refresh_openclaw_bridge_and_test(
302
304
  f"npm:{OPENCLAW_PLUGIN_PACKAGE}@{OPENCLAW_PLUGIN_VERSION}",
303
305
  "--pin",
304
306
  "--force",
307
+ *capability_consent,
305
308
  ]
306
309
  ),
307
310
  "OpenClaw bridge upgrade",
@@ -338,6 +341,7 @@ def refresh_openclaw_bridge_and_test(
338
341
  f"npm:{OPENCLAW_PLUGIN_PACKAGE}@{prior_version}",
339
342
  "--pin",
340
343
  "--force",
344
+ *capability_consent,
341
345
  ]
342
346
  ),
343
347
  "prior bridge restore",
@@ -393,6 +397,7 @@ def refresh_openclaw_bridge_and_test(
393
397
  return {
394
398
  "format": "atmem-openclaw-bridge-refresh-v1",
395
399
  "refreshed": True,
400
+ "bridge_package_changed": package_changed,
396
401
  "previous_bridge_version": prior_version,
397
402
  "bridge_version": OPENCLAW_PLUGIN_VERSION,
398
403
  "mode": state.mode.value,
@@ -457,6 +462,16 @@ def _resolve_engine(explicit: str | None) -> str:
457
462
  return str(path)
458
463
 
459
464
 
465
+ def _capability_consent_arguments(version_output: str) -> list[str]:
466
+ """Return the explicit plugin-consent flag introduced by OpenClaw 2.0."""
467
+
468
+ match = re.search(r"\b(\d{4})\.(\d+)\.(\d+)(?:\D|$)", version_output)
469
+ if match is None:
470
+ return []
471
+ release = tuple(int(part) for part in match.groups())
472
+ return ["--accept-capabilities"] if release >= (2026, 8, 1) else []
473
+
474
+
460
475
  def _verify_engine(engine: str, run: Runner) -> str:
461
476
  result = run([engine, "--version"])
462
477
  _require_success(result, "AtMem engine version check")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atmem
3
- Version: 2.2.3
3
+ Version: 2.2.4
4
4
  Summary: Host-neutral Agent Black Box and reversible memory control plane.
5
5
  Author-email: aetna000 <aetna000@gmail.com>
6
6
  Maintainer-email: aetna000 <aetna000@gmail.com>
@@ -24,7 +24,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
24
  Requires-Python: >=3.10
25
25
  Description-Content-Type: text/markdown
26
26
  License-File: LICENSE
27
- Requires-Dist: atmem-atbot==0.1.0a2
27
+ Requires-Dist: atmem-atbot==0.1.0a3
28
28
  Provides-Extra: dev
29
29
  Requires-Dist: pytest>=8.0.0; extra == "dev"
30
30
  Requires-Dist: tomli>=2.0; python_version < "3.11" and extra == "dev"
@@ -44,7 +44,7 @@ Dynamic: license-file
44
44
 
45
45
  # AtMem
46
46
 
47
- [![Version 2.2.3](https://img.shields.io/badge/version-2.2.3-blue)](./docs/releases/v2.2.3.md)
47
+ [![Version 2.2.4](https://img.shields.io/badge/version-2.2.4-blue)](./docs/releases/v2.2.4.md)
48
48
  [![CI](https://github.com/aetna000/atmem/actions/workflows/ci.yml/badge.svg)](https://github.com/aetna000/atmem/actions/workflows/ci.yml)
49
49
 
50
50
  **AtMem is a host-neutral Agent Black Box and reversible memory control plane.**
@@ -59,7 +59,7 @@ authorizes, stores, scopes, injects, corrects, and deletes memory.
59
59
  ### 1. Install AtMem and choose memory intelligence
60
60
 
61
61
  ```bash
62
- python -m pip install --upgrade atmem==2.2.3
62
+ python -m pip install --upgrade atmem==2.2.4
63
63
  atmem atbot setup
64
64
  atmem atbot doctor
65
65
  atmem dashboard
@@ -87,15 +87,30 @@ connection. Do not install the npm package yourself.
87
87
  Already using AtMem 2.1 with OpenClaw? Upgrade in place:
88
88
 
89
89
  ```bash
90
- python -m pip install --upgrade atmem==2.2.3
90
+ python -m pip install --upgrade atmem==2.2.4
91
91
  atmem openclaw upgrade
92
92
  atmem control verify
93
93
  ```
94
94
 
95
+ The upgrade command is idempotent. It replaces a running dashboard with the
96
+ new Python runtime before refreshing and testing the OpenClaw bridge, so the UI
97
+ cannot continue serving the pre-upgrade package version.
98
+
99
+ For Pydantic AI, LangGraph, or another non-OpenClaw integration, finish an
100
+ upgrade by restarting a background dashboard directly:
101
+
102
+ ```bash
103
+ python -m pip install --upgrade atmem
104
+ atmem dashboard daemon restart
105
+ ```
106
+
107
+ Using `python -m pip` is important: it upgrades the same Python environment
108
+ selected by `python`, rather than an unrelated `pip` executable on `PATH`.
109
+
95
110
  #### Pydantic AI — native capability
96
111
 
97
112
  ```bash
98
- python -m pip install 'atmem[pydantic-ai]==2.2.3'
113
+ python -m pip install 'atmem[pydantic-ai]==2.2.4'
99
114
  atmem control shadow --host generic --memory-db ~/.atmem/memories.db
100
115
  ```
101
116
 
@@ -119,7 +134,7 @@ agent = Agent("openai:gpt-5-mini", capabilities=[memory])
119
134
  #### LangChain/LangGraph — native middleware
120
135
 
121
136
  ```bash
122
- python -m pip install 'atmem[langgraph]==2.2.3'
137
+ python -m pip install 'atmem[langgraph]==2.2.4'
123
138
  atmem control shadow --host generic --memory-db ~/.atmem/memories.db
124
139
  ```
125
140
 
@@ -163,7 +178,7 @@ If AtBot or its selected model is unavailable, AtMem continues with safe local
163
178
  capture and hybrid ranking. Memory authority and agent operation do not depend
164
179
  on a hosted model.
165
180
 
166
- > **Release status:** this repository describes **AtMem 2.2.3**. AtBot is a
181
+ > **Release status:** this repository describes **AtMem 2.2.4**. AtBot is a
167
182
  > separately packaged, headless component installed and managed by AtMem; it is
168
183
  > not an independent agent or a second memory authority.
169
184
 
@@ -182,7 +197,7 @@ and restores it exactly.
182
197
  ## Installation details
183
198
 
184
199
  ```bash
185
- python -m pip install atmem==2.2.3
200
+ python -m pip install atmem==2.2.4
186
201
  atmem --version
187
202
  ```
188
203
 
@@ -190,7 +205,7 @@ AtMem requires Python 3.10 or newer. It always creates a dependency-free local
190
205
  vector sidecar; the semantic extra adds an optional local embedding upgrade:
191
206
 
192
207
  ```bash
193
- python -m pip install 'atmem[semantic]==2.2.3'
208
+ python -m pip install 'atmem[semantic]==2.2.4'
194
209
  ```
195
210
 
196
211
  For repository development, install both workspace packages:
@@ -370,7 +385,7 @@ atmem control restore
370
385
  Existing 2.1 installations upgrade without starting a new migration:
371
386
 
372
387
  ```bash
373
- python -m pip install --upgrade atmem==2.2.3
388
+ python -m pip install --upgrade atmem==2.2.4
374
389
  atmem openclaw upgrade
375
390
  atmem control verify
376
391
  ```
@@ -516,7 +531,7 @@ npm test
516
531
  npm run smoke
517
532
  ```
518
533
 
519
- Current repository metadata is version **2.2.3**. Python and npm release
534
+ Current repository metadata is version **2.2.4**. Python and npm release
520
535
  versions are intentionally kept equal because the OpenClaw installer pins the
521
536
  matching bridge.
522
537
 
@@ -95,6 +95,7 @@ docs/releases/v2.2.0.md
95
95
  docs/releases/v2.2.1.md
96
96
  docs/releases/v2.2.2.md
97
97
  docs/releases/v2.2.3.md
98
+ docs/releases/v2.2.4.md
98
99
  integrations/openclaw/README.md
99
100
  integrations/openclaw/index.ts
100
101
  integrations/openclaw/openclaw.plugin.json
@@ -1,4 +1,4 @@
1
- atmem-atbot==0.1.0a2
1
+ atmem-atbot==0.1.0a3
2
2
 
3
3
  [atbot]
4
4
 
@@ -31,7 +31,7 @@ stored in GitHub.
31
31
  2. Run both Python suites and build both distributions locally.
32
32
  3. Push the reviewed changes.
33
33
  4. Create and push a tag matching `atbot-v<VERSION>`, for example
34
- `atbot-v0.1.0a2`.
34
+ `atbot-v0.1.0a3`.
35
35
  5. Approve the protected `pypi-atbot` environment deployment.
36
36
  6. Confirm `python -m pip install atmem-atbot==<VERSION>` installs an `atbot`
37
37
  command with the same version.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "product": "memory_control_plane",
3
- "version": "2.2.3",
3
+ "version": "2.2.4",
4
4
  "development_target": null,
5
5
  "release_status": "released",
6
6
  "engine": "model_agnostic",
@@ -8,7 +8,7 @@
8
8
  "intelligence_companion": {
9
9
  "package": "atbot",
10
10
  "distribution": "atmem-atbot",
11
- "pinned_version": "0.1.0a2",
11
+ "pinned_version": "0.1.0a3",
12
12
  "required_distribution_dependency": true,
13
13
  "separate_process": true,
14
14
  "loopback_protocol": "1",