memgres 0.5.2__tar.gz → 0.6.0__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 (92) hide show
  1. {memgres-0.5.2 → memgres-0.6.0}/PKG-INFO +24 -3
  2. {memgres-0.5.2 → memgres-0.6.0}/README.md +23 -2
  3. {memgres-0.5.2 → memgres-0.6.0}/memgres/__init__.py +4 -2
  4. {memgres-0.5.2 → memgres-0.6.0}/memgres/_version.py +1 -1
  5. memgres-0.6.0/memgres/admin.py +552 -0
  6. {memgres-0.5.2 → memgres-0.6.0}/memgres/admin_cli.py +8 -7
  7. {memgres-0.5.2 → memgres-0.6.0}/memgres/config.py +4 -0
  8. memgres-0.6.0/memgres/delimiters.py +88 -0
  9. memgres-0.6.0/memgres/identity.py +1252 -0
  10. {memgres-0.5.2 → memgres-0.6.0}/memgres/info.py +3 -0
  11. memgres-0.6.0/memgres/lines.py +65 -0
  12. memgres-0.6.0/memgres/mcp_server.py +1006 -0
  13. {memgres-0.5.2 → memgres-0.6.0}/memgres/migrations/0002_identity.sql +13 -3
  14. memgres-0.6.0/memgres/migrations/0009_create_namespace_right.sql +23 -0
  15. memgres-0.6.0/memgres/migrations/0010_namespace_alias.sql +24 -0
  16. memgres-0.6.0/memgres/migrations/0011_drop_default_namespace.sql +23 -0
  17. memgres-0.6.0/memgres/migrations/0012_user_profile.sql +30 -0
  18. memgres-0.6.0/memgres/migrations/0013_hash_version.sql +28 -0
  19. memgres-0.6.0/memgres/migrations/0014_access_request_no_fk.sql +24 -0
  20. {memgres-0.5.2 → memgres-0.6.0}/memgres/schema.py +17 -2
  21. {memgres-0.5.2 → memgres-0.6.0}/memgres/search.py +16 -10
  22. memgres-0.6.0/memgres/server.py +637 -0
  23. memgres-0.6.0/memgres/store.py +1204 -0
  24. {memgres-0.5.2 → memgres-0.6.0}/memgres/vector/base.py +43 -9
  25. {memgres-0.5.2 → memgres-0.6.0}/memgres/vector/pgvector.py +14 -4
  26. {memgres-0.5.2 → memgres-0.6.0}/memgres/vector/qdrant.py +38 -5
  27. {memgres-0.5.2 → memgres-0.6.0}/memgres.egg-info/PKG-INFO +24 -3
  28. {memgres-0.5.2 → memgres-0.6.0}/memgres.egg-info/SOURCES.txt +15 -1
  29. {memgres-0.5.2 → memgres-0.6.0}/tests/test_chunk_index.py +117 -0
  30. {memgres-0.5.2 → memgres-0.6.0}/tests/test_diffing.py +29 -4
  31. memgres-0.6.0/tests/test_identity_integration.py +589 -0
  32. {memgres-0.5.2 → memgres-0.6.0}/tests/test_list.py +65 -1
  33. memgres-0.6.0/tests/test_mcp_admin_tools.py +323 -0
  34. {memgres-0.5.2 → memgres-0.6.0}/tests/test_mcp_recall_schema.py +26 -0
  35. memgres-0.6.0/tests/test_mcp_tool_visibility.py +346 -0
  36. {memgres-0.5.2 → memgres-0.6.0}/tests/test_migration_upgrade.py +38 -0
  37. memgres-0.6.0/tests/test_multi_space_search.py +367 -0
  38. memgres-0.6.0/tests/test_path_addressing.py +223 -0
  39. {memgres-0.5.2 → memgres-0.6.0}/tests/test_roles_bootstrap.py +122 -0
  40. memgres-0.6.0/tests/test_security_integration.py +678 -0
  41. {memgres-0.5.2 → memgres-0.6.0}/tests/test_segments_store.py +4 -0
  42. {memgres-0.5.2 → memgres-0.6.0}/tests/test_server_info.py +4 -1
  43. {memgres-0.5.2 → memgres-0.6.0}/tests/test_server_integration.py +193 -6
  44. {memgres-0.5.2 → memgres-0.6.0}/tests/test_store_integration.py +155 -1
  45. memgres-0.6.0/tests/test_write_ergonomics.py +212 -0
  46. memgres-0.5.2/memgres/identity.py +0 -559
  47. memgres-0.5.2/memgres/mcp_server.py +0 -446
  48. memgres-0.5.2/memgres/server.py +0 -514
  49. memgres-0.5.2/memgres/store.py +0 -664
  50. memgres-0.5.2/tests/test_identity_integration.py +0 -325
  51. memgres-0.5.2/tests/test_security_integration.py +0 -263
  52. {memgres-0.5.2 → memgres-0.6.0}/LICENSE +0 -0
  53. {memgres-0.5.2 → memgres-0.6.0}/memgres/blame.py +0 -0
  54. {memgres-0.5.2 → memgres-0.6.0}/memgres/bootstrap.py +0 -0
  55. {memgres-0.5.2 → memgres-0.6.0}/memgres/diffing.py +0 -0
  56. {memgres-0.5.2 → memgres-0.6.0}/memgres/embed_worker.py +0 -0
  57. {memgres-0.5.2 → memgres-0.6.0}/memgres/embeddings.py +0 -0
  58. {memgres-0.5.2 → memgres-0.6.0}/memgres/healthcheck.py +0 -0
  59. {memgres-0.5.2 → memgres-0.6.0}/memgres/indexing.py +0 -0
  60. {memgres-0.5.2 → memgres-0.6.0}/memgres/migrations/0001_core.sql +0 -0
  61. {memgres-0.5.2 → memgres-0.6.0}/memgres/migrations/0003_history_author.sql +0 -0
  62. {memgres-0.5.2 → memgres-0.6.0}/memgres/migrations/0004_title.sql +0 -0
  63. {memgres-0.5.2 → memgres-0.6.0}/memgres/migrations/0005_chunk_index.sql +0 -0
  64. {memgres-0.5.2 → memgres-0.6.0}/memgres/migrations/0006_reader_floor.sql +0 -0
  65. {memgres-0.5.2 → memgres-0.6.0}/memgres/migrations/0007_embed_retry.sql +0 -0
  66. {memgres-0.5.2 → memgres-0.6.0}/memgres/migrations/0008_service_roles.sql +0 -0
  67. {memgres-0.5.2 → memgres-0.6.0}/memgres/reembed.py +0 -0
  68. {memgres-0.5.2 → memgres-0.6.0}/memgres/segments.py +0 -0
  69. {memgres-0.5.2 → memgres-0.6.0}/memgres/vector/__init__.py +0 -0
  70. {memgres-0.5.2 → memgres-0.6.0}/memgres/worker.py +0 -0
  71. {memgres-0.5.2 → memgres-0.6.0}/memgres.egg-info/dependency_links.txt +0 -0
  72. {memgres-0.5.2 → memgres-0.6.0}/memgres.egg-info/entry_points.txt +0 -0
  73. {memgres-0.5.2 → memgres-0.6.0}/memgres.egg-info/requires.txt +0 -0
  74. {memgres-0.5.2 → memgres-0.6.0}/memgres.egg-info/top_level.txt +0 -0
  75. {memgres-0.5.2 → memgres-0.6.0}/pyproject.toml +0 -0
  76. {memgres-0.5.2 → memgres-0.6.0}/setup.cfg +0 -0
  77. {memgres-0.5.2 → memgres-0.6.0}/tests/test_blame_integration.py +0 -0
  78. {memgres-0.5.2 → memgres-0.6.0}/tests/test_claim_and_reembed.py +0 -0
  79. {memgres-0.5.2 → memgres-0.6.0}/tests/test_config.py +0 -0
  80. {memgres-0.5.2 → memgres-0.6.0}/tests/test_embed_worker.py +0 -0
  81. {memgres-0.5.2 → memgres-0.6.0}/tests/test_embeddings.py +0 -0
  82. {memgres-0.5.2 → memgres-0.6.0}/tests/test_healthcheck.py +0 -0
  83. {memgres-0.5.2 → memgres-0.6.0}/tests/test_lexical_match.py +0 -0
  84. {memgres-0.5.2 → memgres-0.6.0}/tests/test_limits.py +0 -0
  85. {memgres-0.5.2 → memgres-0.6.0}/tests/test_mcp_http_transport.py +0 -0
  86. {memgres-0.5.2 → memgres-0.6.0}/tests/test_mcp_instructions.py +0 -0
  87. {memgres-0.5.2 → memgres-0.6.0}/tests/test_qdrant_ca.py +0 -0
  88. {memgres-0.5.2 → memgres-0.6.0}/tests/test_qdrant_integration.py +0 -0
  89. {memgres-0.5.2 → memgres-0.6.0}/tests/test_replace_build.py +0 -0
  90. {memgres-0.5.2 → memgres-0.6.0}/tests/test_search_integration.py +0 -0
  91. {memgres-0.5.2 → memgres-0.6.0}/tests/test_segments.py +0 -0
  92. {memgres-0.5.2 → memgres-0.6.0}/tests/test_snippets.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memgres
3
- Version: 0.5.2
3
+ Version: 0.6.0
4
4
  Summary: Drop-in memory for AI agents: one Postgres, lexical + semantic recall, diff-versioned history, GDPR-erasable.
5
5
  Author: mozgsml
6
6
  License-Expression: MIT
@@ -220,6 +220,9 @@ Everything is env, all optional (defaults suit a single-user embed). Full list i
220
220
  | `MEMGRES_FULL_BODY` | `false` | force the whole body on every hit (off = auto: short whole, long sliced); `full_body` per call overrides |
221
221
  | `MEMGRES_FULL_BODY_MAX_CHARS` | `500` | a body this short is returned whole (`kind="full"`) instead of sliced |
222
222
  | `MEMGRES_LIST_PREVIEW_CHARS` | `120` | first-line preview length returned by `memory_list` |
223
+ | `MEMGRES_LIST_BODIES_MAX_BYTES` | `200000` | total body bytes one `bodies=true` browse returns; rows past the cap come back marked `body_omitted`, never dropped |
224
+ | `MEMGRES_MCP_ADMIN_TOOLS` | `auto` | register the `memory_admin_*` control-plane tools over MCP; `auto` = every mode but `single`. A context economy, not a security boundary — each tool authorizes on call |
225
+ | `MEMGRES_MCP_TOOL_VISIBILITY` | `auto` | show each client only the tools its own credential can use, and drop the identity tools where there are no identities (`single`). Display, not authorization — every tool still authorizes on call; `off` lists everything |
223
226
  | `MEMGRES_INSTRUCTION` | — | server-side MCP instructions emitted at `initialize` (a client like Claude Code loads it once at connect); unset = omitted; capped at 2 KB |
224
227
  | `MEMGRES_VECTOR_BACKEND` | `pgvector` | `pgvector` (same DB) or `qdrant` (set `QDRANT_URL`, `QDRANT_API_KEY`, `MEMGRES_QDRANT_COLLECTION`) |
225
228
  | `MEMGRES_EMBED_PROVIDER` | `none` | `none` / `local` / `openai` / `jina` / `openai-compatible` (LM Studio, Ollama, vLLM, TEI…) |
@@ -244,13 +247,31 @@ Everything is env, all optional (defaults suit a single-user embed). Full list i
244
247
  | `GET` | `/memories/{id}/blame` | line attribution; `?group`, `?text`, `?lines=1,3-5` |
245
248
  | `GET` | `/memories/{id}/at/{seq}` | body reconstructed at a version |
246
249
  | `GET` | `/recall` | `?q=&k=&mode=&tags=&path_prefix=&match=&snippet=&full_body=` |
247
- | `GET` | `/memories` | list a subtree, no query: `?path_prefix=&tags=&limit=&offset=` |
250
+ | `GET` | `/memories` | list a subtree, no query: `?path_prefix=&tags=&limit=&offset=&bodies=` |
251
+ | `GET` | `/whoami` | what this token may do, as capabilities |
252
+ | `GET` | `/admin/orphans` | memories stranded by a `single` → managed switch |
253
+ | `POST` | `/admin/adopt-orphans` | move them into a real namespace (idempotent) |
248
254
  | `GET` | `/spaces` | namespaces this token can reach (identity modes) |
255
+ | `POST` | `/spaces` | create one of your own (nothing is created by being named) |
256
+ | `POST` | `/spaces/aliases` | give a reachable namespace a name of your own |
249
257
  | `GET` | `/info` | effective config: limits, embed provider/model/dim, recall modes, backend |
250
258
  | `GET` | `/healthz` | liveness |
251
259
 
260
+ **`{id}` may be a memory's uuid or its tree path** (`/memories/decisions.pricing`)
261
+ — the segment is read as an id when it parses as a uuid, and as a path
262
+ otherwise, so hyphenated and non-ASCII paths (`ops.rate-limits`) address fine.
263
+ A path that a memory has since moved away from is followed on a read
264
+ (the answer sets `moved_from`) and refused on a write, which is what stops an
265
+ edit meant for one memory from quietly becoming a second memory beside it.
266
+
252
267
  Every memory/recall route also takes optional `space` (one of your namespaces by
253
- name) and `space_id` (canonical id, for shared spaces). In `open`/`managed` mode
268
+ name your own, one shared with you, or an **alias** you set) and `space_id`
269
+ (canonical id, always unambiguous); a search takes a list of either, or
270
+ `space=all` — every namespace you belong to, plus `space=*` for every namespace
271
+ in the deployment if you are a superadmin — and each hit says which namespace
272
+ answered. Addressing a namespace that does not exist is an error, never a new
273
+ one. In
274
+ `open`/`managed` mode
254
275
  the token goes in `Authorization: Bearer <token>` or `X-Memgres-Token`; there are
255
276
  also request-access and `/admin/*` provisioning routes — see
256
277
  [docs/TENANCY.md](docs/TENANCY.md). OpenAPI/Swagger is at `/docs`. Store errors
@@ -184,6 +184,9 @@ Everything is env, all optional (defaults suit a single-user embed). Full list i
184
184
  | `MEMGRES_FULL_BODY` | `false` | force the whole body on every hit (off = auto: short whole, long sliced); `full_body` per call overrides |
185
185
  | `MEMGRES_FULL_BODY_MAX_CHARS` | `500` | a body this short is returned whole (`kind="full"`) instead of sliced |
186
186
  | `MEMGRES_LIST_PREVIEW_CHARS` | `120` | first-line preview length returned by `memory_list` |
187
+ | `MEMGRES_LIST_BODIES_MAX_BYTES` | `200000` | total body bytes one `bodies=true` browse returns; rows past the cap come back marked `body_omitted`, never dropped |
188
+ | `MEMGRES_MCP_ADMIN_TOOLS` | `auto` | register the `memory_admin_*` control-plane tools over MCP; `auto` = every mode but `single`. A context economy, not a security boundary — each tool authorizes on call |
189
+ | `MEMGRES_MCP_TOOL_VISIBILITY` | `auto` | show each client only the tools its own credential can use, and drop the identity tools where there are no identities (`single`). Display, not authorization — every tool still authorizes on call; `off` lists everything |
187
190
  | `MEMGRES_INSTRUCTION` | — | server-side MCP instructions emitted at `initialize` (a client like Claude Code loads it once at connect); unset = omitted; capped at 2 KB |
188
191
  | `MEMGRES_VECTOR_BACKEND` | `pgvector` | `pgvector` (same DB) or `qdrant` (set `QDRANT_URL`, `QDRANT_API_KEY`, `MEMGRES_QDRANT_COLLECTION`) |
189
192
  | `MEMGRES_EMBED_PROVIDER` | `none` | `none` / `local` / `openai` / `jina` / `openai-compatible` (LM Studio, Ollama, vLLM, TEI…) |
@@ -208,13 +211,31 @@ Everything is env, all optional (defaults suit a single-user embed). Full list i
208
211
  | `GET` | `/memories/{id}/blame` | line attribution; `?group`, `?text`, `?lines=1,3-5` |
209
212
  | `GET` | `/memories/{id}/at/{seq}` | body reconstructed at a version |
210
213
  | `GET` | `/recall` | `?q=&k=&mode=&tags=&path_prefix=&match=&snippet=&full_body=` |
211
- | `GET` | `/memories` | list a subtree, no query: `?path_prefix=&tags=&limit=&offset=` |
214
+ | `GET` | `/memories` | list a subtree, no query: `?path_prefix=&tags=&limit=&offset=&bodies=` |
215
+ | `GET` | `/whoami` | what this token may do, as capabilities |
216
+ | `GET` | `/admin/orphans` | memories stranded by a `single` → managed switch |
217
+ | `POST` | `/admin/adopt-orphans` | move them into a real namespace (idempotent) |
212
218
  | `GET` | `/spaces` | namespaces this token can reach (identity modes) |
219
+ | `POST` | `/spaces` | create one of your own (nothing is created by being named) |
220
+ | `POST` | `/spaces/aliases` | give a reachable namespace a name of your own |
213
221
  | `GET` | `/info` | effective config: limits, embed provider/model/dim, recall modes, backend |
214
222
  | `GET` | `/healthz` | liveness |
215
223
 
224
+ **`{id}` may be a memory's uuid or its tree path** (`/memories/decisions.pricing`)
225
+ — the segment is read as an id when it parses as a uuid, and as a path
226
+ otherwise, so hyphenated and non-ASCII paths (`ops.rate-limits`) address fine.
227
+ A path that a memory has since moved away from is followed on a read
228
+ (the answer sets `moved_from`) and refused on a write, which is what stops an
229
+ edit meant for one memory from quietly becoming a second memory beside it.
230
+
216
231
  Every memory/recall route also takes optional `space` (one of your namespaces by
217
- name) and `space_id` (canonical id, for shared spaces). In `open`/`managed` mode
232
+ name your own, one shared with you, or an **alias** you set) and `space_id`
233
+ (canonical id, always unambiguous); a search takes a list of either, or
234
+ `space=all` — every namespace you belong to, plus `space=*` for every namespace
235
+ in the deployment if you are a superadmin — and each hit says which namespace
236
+ answered. Addressing a namespace that does not exist is an error, never a new
237
+ one. In
238
+ `open`/`managed` mode
218
239
  the token goes in `Authorization: Bearer <token>` or `X-Memgres-Token`; there are
219
240
  also request-access and `/admin/*` provisioning routes — see
220
241
  [docs/TENANCY.md](docs/TENANCY.md). OpenAPI/Swagger is at `/docs`. Store errors
@@ -27,7 +27,8 @@ from .identity import (
27
27
  Principal, AuthError, SpaceNotFound,
28
28
  resolve, resolve_space, new_token, valid_format,
29
29
  create_user, create_namespace, list_spaces,
30
- issue_token, register_token, revoke_token, list_tokens,
30
+ list_users, list_namespaces, list_members,
31
+ issue_token, register_token, revoke_token, list_tokens, token_owner,
31
32
  request_access, approve_request, deny_request, list_requests,
32
33
  )
33
34
 
@@ -43,6 +44,7 @@ __all__ = [
43
44
  "Principal", "AuthError", "SpaceNotFound",
44
45
  "resolve", "resolve_space", "new_token", "valid_format",
45
46
  "create_user", "create_namespace", "list_spaces",
46
- "issue_token", "register_token", "revoke_token", "list_tokens",
47
+ "list_users", "list_namespaces", "list_members",
48
+ "issue_token", "register_token", "revoke_token", "list_tokens", "token_owner",
47
49
  "request_access", "approve_request", "deny_request", "list_requests",
48
50
  ]
@@ -8,4 +8,4 @@ here at release; nowhere else carries the number.
8
8
  PEP 440: a ``.devN`` suffix marks an unreleased build ahead of the last tag.
9
9
  """
10
10
 
11
- __version__ = "0.5.2"
11
+ __version__ = "0.6.0"