memmachine-server 0.2.2__tar.gz → 0.2.3__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 (168) hide show
  1. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/PKG-INFO +8 -1
  2. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/README.md +7 -0
  3. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/pyproject.toml +5 -2
  4. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/__init__.py +1 -0
  5. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/api/doc.py +5 -0
  6. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/api/spec.py +8 -0
  7. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/episode_store/episode_model.py +1 -0
  8. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/session_manager/session_data_manager_sql_impl.py +79 -12
  9. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/vector_graph_store/neo4j_vector_graph_store.py +2 -3
  10. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/declarative_memory/declarative_memory.py +64 -21
  11. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/episodic_memory.py +21 -11
  12. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/long_term_memory/long_term_memory.py +33 -6
  13. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/main/memmachine.py +4 -0
  14. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/rest_client/memory.py +3 -0
  15. memmachine_server-0.2.3/src/memmachine/semantic_memory/storage/alembic_pg/script.py.mako +28 -0
  16. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/api_v2/mcp.py +4 -1
  17. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/api_v2/router.py +9 -36
  18. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/api_v2/service.py +35 -2
  19. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/app.py +42 -13
  20. memmachine_server-0.2.3/src/memmachine-ts/rest_client/.gitignore +30 -0
  21. memmachine_server-0.2.3/src/memmachine-ts/rest_client/.prettierignore +18 -0
  22. memmachine_server-0.2.3/src/memmachine-ts/rest_client/.prettierrc +15 -0
  23. memmachine_server-0.2.3/src/memmachine-ts/rest_client/README.md +156 -0
  24. memmachine_server-0.2.3/src/memmachine-ts/rest_client/eslint.config.mjs +19 -0
  25. memmachine_server-0.2.3/src/memmachine-ts/rest_client/jest.config.ts +20 -0
  26. memmachine_server-0.2.3/src/memmachine-ts/rest_client/package-lock.json +10073 -0
  27. memmachine_server-0.2.3/src/memmachine-ts/rest_client/package.json +93 -0
  28. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/client/index.ts +9 -0
  29. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/client/memmachine-client.ts +118 -0
  30. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/client/memmachine-client.types.ts +34 -0
  31. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/env.d.ts +1 -0
  32. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/errors/api-error-handler.ts +20 -0
  33. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/errors/index.ts +8 -0
  34. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/errors/memmachine-api-error.ts +14 -0
  35. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/index.ts +13 -0
  36. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/memory/index.ts +20 -0
  37. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/memory/memmachine-memory.ts +315 -0
  38. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/memory/memmachine-memory.types.ts +166 -0
  39. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/project/index.ts +9 -0
  40. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/project/memmachine-project.ts +167 -0
  41. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/project/memmachine-project.types.ts +41 -0
  42. memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/version.ts +1 -0
  43. memmachine_server-0.2.3/src/memmachine-ts/rest_client/tests/api-error-handler.spec.ts +36 -0
  44. memmachine_server-0.2.3/src/memmachine-ts/rest_client/tests/index.spec.ts +11 -0
  45. memmachine_server-0.2.3/src/memmachine-ts/rest_client/tests/memmachine-client.spec.ts +52 -0
  46. memmachine_server-0.2.3/src/memmachine-ts/rest_client/tests/memmachine-memory.spec.ts +149 -0
  47. memmachine_server-0.2.3/src/memmachine-ts/rest_client/tests/memmachine-project.spec.ts +101 -0
  48. memmachine_server-0.2.3/src/memmachine-ts/rest_client/tsconfig.json +44 -0
  49. memmachine_server-0.2.3/src/memmachine-ts/rest_client/tsup.config.ts +14 -0
  50. memmachine_server-0.2.3/src/memmachine-ts/rest_client/typedoc.json +4 -0
  51. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine_server.egg-info/PKG-INFO +8 -1
  52. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine_server.egg-info/SOURCES.txt +32 -0
  53. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/LICENSE +0 -0
  54. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/setup.cfg +0 -0
  55. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/__init__.py +0 -0
  56. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/api/__init__.py +0 -0
  57. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/__init__.py +0 -0
  58. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/database_conf.py +0 -0
  59. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/default_episode_summary_system_prompt.txt +0 -0
  60. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/default_episode_summary_user_prompt.txt +0 -0
  61. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/embedder_conf.py +0 -0
  62. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/episodic_config.py +0 -0
  63. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/language_model_conf.py +0 -0
  64. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/log_conf.py +0 -0
  65. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/mixin_confs.py +0 -0
  66. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/reranker_conf.py +0 -0
  67. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/data_types.py +0 -0
  68. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/embedder/__init__.py +0 -0
  69. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/embedder/amazon_bedrock_embedder.py +0 -0
  70. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/embedder/embedder.py +0 -0
  71. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/embedder/openai_embedder.py +0 -0
  72. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/embedder/sentence_transformer_embedder.py +0 -0
  73. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/episode_store/__init__.py +0 -0
  74. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/episode_store/count_caching_episode_storage.py +0 -0
  75. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/episode_store/episode_sqlalchemy_store.py +0 -0
  76. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/episode_store/episode_storage.py +0 -0
  77. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/errors.py +0 -0
  78. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/filter/__init__.py +0 -0
  79. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/filter/filter_parser.py +0 -0
  80. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/filter/sql_filter_util.py +0 -0
  81. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/language_model/__init__.py +0 -0
  82. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/language_model/amazon_bedrock_language_model.py +0 -0
  83. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/language_model/language_model.py +0 -0
  84. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/language_model/openai_chat_completions_language_model.py +0 -0
  85. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/language_model/openai_responses_language_model.py +0 -0
  86. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/metrics_factory/__init__.py +0 -0
  87. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/metrics_factory/metrics_factory.py +0 -0
  88. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/metrics_factory/prometheus_metrics_factory.py +0 -0
  89. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/__init__.py +0 -0
  90. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/amazon_bedrock_reranker.py +0 -0
  91. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/bm25_reranker.py +0 -0
  92. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/cohere_reranker.py +0 -0
  93. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/cross_encoder_reranker.py +0 -0
  94. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/embedder_reranker.py +0 -0
  95. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/identity_reranker.py +0 -0
  96. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/reranker.py +0 -0
  97. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/rrf_hybrid_reranker.py +0 -0
  98. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/resource_manager/__init__.py +0 -0
  99. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/resource_manager/database_manager.py +0 -0
  100. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/resource_manager/embedder_manager.py +0 -0
  101. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/resource_manager/language_model_manager.py +0 -0
  102. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/resource_manager/reranker_manager.py +0 -0
  103. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/resource_manager/resource_manager.py +0 -0
  104. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/resource_manager/semantic_manager.py +0 -0
  105. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/session_manager/__init__.py +0 -0
  106. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/session_manager/session_data_manager.py +0 -0
  107. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/utils.py +0 -0
  108. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/vector_graph_store/__init__.py +0 -0
  109. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/vector_graph_store/data_types.py +0 -0
  110. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/vector_graph_store/vector_graph_store.py +0 -0
  111. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/__init__.py +0 -0
  112. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/declarative_memory/__init__.py +0 -0
  113. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/declarative_memory/data_types.py +0 -0
  114. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/episodic_memory_manager.py +0 -0
  115. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/instance_lru_cache.py +0 -0
  116. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/long_term_memory/__init__.py +0 -0
  117. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/long_term_memory/service_locator.py +0 -0
  118. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/service_locator.py +0 -0
  119. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/short_term_memory/__init__.py +0 -0
  120. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/short_term_memory/service_locator.py +0 -0
  121. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/short_term_memory/short_term_memory.py +0 -0
  122. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/installation/__init__.py +0 -0
  123. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/installation/configuration_wizard.py +0 -0
  124. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/installation/memmachine_configure.py +0 -0
  125. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/installation/utilities.py +0 -0
  126. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/main/__init__.py +0 -0
  127. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/rest_client/README.md +0 -0
  128. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/rest_client/__init__.py +0 -0
  129. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/rest_client/client.py +0 -0
  130. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/rest_client/project.py +0 -0
  131. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/__init__.py +0 -0
  132. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/semantic_ingestion.py +0 -0
  133. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/semantic_llm.py +0 -0
  134. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/semantic_memory.py +0 -0
  135. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/semantic_model.py +0 -0
  136. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/semantic_session_manager.py +0 -0
  137. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/__init__.py +0 -0
  138. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/alembic_pg/__init__.py +0 -0
  139. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/alembic_pg/env.py +0 -0
  140. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/alembic_pg/versions/001_initial_migration.py +0 -0
  141. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/alembic_pg/versions/3d6aaebdc526_sync_sqlalchemy_schema.py +0 -0
  142. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/alembic_pg/versions/62dff1150a46_add_created_at_to_history_add.py +0 -0
  143. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/alembic_pg/versions/79f00a9f2409_change_history_id_to_string.py +0 -0
  144. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/alembic_pg/versions/843f6d216d10_rename_semantic_type_to_semantic_.py +0 -0
  145. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/alembic_pg/versions/__init__.py +0 -0
  146. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/alembic_pg/versions/adb5618bd4ee_remove_history_table.py +0 -0
  147. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/neo4j_semantic_storage.py +0 -0
  148. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/sqlalchemy_pgvector_semantic.py +0 -0
  149. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/storage_base.py +0 -0
  150. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/util/__init__.py +0 -0
  151. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/util/semantic_prompt_template.py +0 -0
  152. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/__init__.py +0 -0
  153. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/api_v2/__init__.py +0 -0
  154. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/mcp_http.py +0 -0
  155. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/mcp_stdio.py +0 -0
  156. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/__init__.py +0 -0
  157. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/coding_style_prompt.py +0 -0
  158. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/crm_prompt.py +0 -0
  159. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/default_prompts.py +0 -0
  160. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/financial_analyst_prompt.py +0 -0
  161. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/health_assistant_prompt.py +0 -0
  162. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/profile_prompt.py +0 -0
  163. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/prompt_utilities.py +0 -0
  164. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/writing_assistant_prompt.py +0 -0
  165. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine_server.egg-info/dependency_links.txt +0 -0
  166. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine_server.egg-info/entry_points.txt +0 -0
  167. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine_server.egg-info/requires.txt +0 -0
  168. {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine_server.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memmachine-server
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: MemMachine Server - The complete MemMachine memory system server with episodic and profile memory
5
5
  Author-email: MemMachine <noreply@memmachine.ai>
6
6
  License-Expression: Apache-2.0
@@ -43,9 +43,16 @@ Dynamic: license-file
43
43
 
44
44
  <div align="center">
45
45
 
46
+ ![GitHub Release Version](https://img.shields.io/github/v/release/memmachine/memmachine?display_name=release)
46
47
  ![Discord](https://img.shields.io/discord/1412878659479666810)
47
48
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/MemMachine/MemMachine)
48
49
  ![GitHub License](https://img.shields.io/github/license/MemMachine/MemMachine)
50
+ <br/>
51
+ ![Docker Pulls](https://img.shields.io/docker/pulls/memmachine/memmachine)
52
+ ![GitHub Downloads](https://img.shields.io/github/downloads/memmachine/memmachine/total?label=GitHub%20Downloads)
53
+ <br/>
54
+ ![PyPI Downloads - memmachine-client](https://img.shields.io/pypi/dm/memmachine-client?label=PyPI%20Downloads%3A%20memmachine-client)
55
+ ![PyPI Downloads - memmachine-server](https://img.shields.io/pypi/dm/memmachine-server?label=PyPI%20Downloads%3A%20memmachine-server)
49
56
 
50
57
  </div>
51
58
 
@@ -2,9 +2,16 @@
2
2
 
3
3
  <div align="center">
4
4
 
5
+ ![GitHub Release Version](https://img.shields.io/github/v/release/memmachine/memmachine?display_name=release)
5
6
  ![Discord](https://img.shields.io/discord/1412878659479666810)
6
7
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/MemMachine/MemMachine)
7
8
  ![GitHub License](https://img.shields.io/github/license/MemMachine/MemMachine)
9
+ <br/>
10
+ ![Docker Pulls](https://img.shields.io/docker/pulls/memmachine/memmachine)
11
+ ![GitHub Downloads](https://img.shields.io/github/downloads/memmachine/memmachine/total?label=GitHub%20Downloads)
12
+ <br/>
13
+ ![PyPI Downloads - memmachine-client](https://img.shields.io/pypi/dm/memmachine-client?label=PyPI%20Downloads%3A%20memmachine-client)
14
+ ![PyPI Downloads - memmachine-server](https://img.shields.io/pypi/dm/memmachine-server?label=PyPI%20Downloads%3A%20memmachine-server)
8
15
 
9
16
  </div>
10
17
 
@@ -1,10 +1,10 @@
1
1
  [build-system]
2
- requires = ["setuptools>=68.0", "wheel"]
2
+ requires = ["setuptools>=68.0", "wheel", "setuptools-scm>=8.0"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "memmachine-server"
7
- version = "v0.2.2"
7
+ dynamic = ["version"]
8
8
  dependencies = [
9
9
  "alembic>=1.17.1",
10
10
  "asyncpg>=0.31.0",
@@ -96,3 +96,6 @@ packages = [
96
96
 
97
97
  [tool.setuptools.package-dir]
98
98
  "" = "src"
99
+
100
+ [tool.setuptools_scm]
101
+ root = "../.."
@@ -1,5 +1,6 @@
1
1
  """Public package exports and utilities for MemMachine."""
2
2
 
3
+ from memmachine.common import api # noqa: F401
3
4
  from memmachine.rest_client import MemMachineClient, Memory, Project
4
5
 
5
6
  try:
@@ -128,6 +128,10 @@ class SpecDoc:
128
128
  The maximum number of memories to return in the search results.
129
129
  """
130
130
 
131
+ SCORE_THRESHOLD = """
132
+ The minimum score for a memory to be included in the search results. Defaults to -inf (no threshold) represented as None. Meaningful only for certain ranking methods.
133
+ """
134
+
131
135
  QUERY = """
132
136
  The natural language query used for semantic memory search. This should be
133
137
  a descriptive string of the information you are looking for.
@@ -208,6 +212,7 @@ class Examples:
208
212
  RERANKER: ClassVar[list[str]] = ["bge-reranker-large", "my-custom-reranker"]
209
213
  EMBEDDER: ClassVar[list[str]] = ["bge-base-en", "my-embedder"]
210
214
  TOP_K: ClassVar[list[int]] = [5, 10, 20]
215
+ SCORE_THRESHOLD: ClassVar[list[float | None]] = [0.0, 0.5, None]
211
216
  QUERY: ClassVar[list[str]] = [
212
217
  "What was the user's last conversation about finance?"
213
218
  ]
@@ -392,6 +392,14 @@ class SearchMemoriesSpec(_WithOrgAndProj):
392
392
  examples=Examples.FILTER_MEM,
393
393
  ),
394
394
  ]
395
+ score_threshold: Annotated[
396
+ float | None,
397
+ Field(
398
+ default=None,
399
+ description=SpecDoc.SCORE_THRESHOLD,
400
+ examples=Examples.SCORE_THRESHOLD,
401
+ ),
402
+ ]
395
403
  types: Annotated[
396
404
  list[MemoryType],
397
405
  Field(
@@ -35,6 +35,7 @@ class EpisodeResponse(EpisodeEntry):
35
35
  """Episode data returned in responses."""
36
36
 
37
37
  uid: EpisodeIdT
38
+ score: float | None = None
38
39
 
39
40
 
40
41
  class Episode(BaseModel):
@@ -1,6 +1,6 @@
1
1
  """Manages database for session config and short term data."""
2
2
 
3
- import io
3
+ import json
4
4
  import os
5
5
  import pickle
6
6
  from typing import Annotated, Any
@@ -9,17 +9,18 @@ from sqlalchemy import (
9
9
  JSON,
10
10
  ForeignKeyConstraint,
11
11
  Integer,
12
- LargeBinary,
13
12
  PrimaryKeyConstraint,
14
13
  String,
15
14
  and_,
16
15
  func,
17
16
  insert,
17
+ inspect,
18
18
  select,
19
+ text,
19
20
  update,
20
21
  )
21
22
  from sqlalchemy.dialects.postgresql import JSONB
22
- from sqlalchemy.ext.asyncio import AsyncEngine, async_sessionmaker
23
+ from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine, async_sessionmaker
23
24
  from sqlalchemy.orm import (
24
25
  DeclarativeBase,
25
26
  Mapped,
@@ -44,7 +45,6 @@ IntColumn = Annotated[int, mapped_column(Integer)]
44
45
  StringKeyColumn = Annotated[str, mapped_column(String, primary_key=True)]
45
46
  StringColumn = Annotated[str, mapped_column(String)]
46
47
  JSONColumn = Annotated[dict, mapped_column(JSON_AUTO)]
47
- BinaryColumn = Annotated[bytes, mapped_column(LargeBinary)]
48
48
 
49
49
 
50
50
  class SessionDataManagerSQL(SessionDataManager):
@@ -57,7 +57,7 @@ class SessionDataManagerSQL(SessionDataManager):
57
57
  session_key: Mapped[StringKeyColumn]
58
58
  timestamp: Mapped[IntColumn]
59
59
  configuration: Mapped[JSONColumn]
60
- param_data: Mapped[BinaryColumn]
60
+ param_data: Mapped[JSONColumn]
61
61
  description: Mapped[StringColumn]
62
62
  user_metadata: Mapped[JSONColumn]
63
63
  __table_args__ = (PrimaryKeyConstraint("session_key"),)
@@ -93,7 +93,24 @@ class SessionDataManagerSQL(SessionDataManager):
93
93
 
94
94
  async def create_tables(self) -> None:
95
95
  """Create the necessary tables in the database."""
96
+
97
+ def _check_migration_needed(conn: AsyncConnection) -> bool:
98
+ inspector = inspect(conn)
99
+ schema = self.SessionConfig.__table__.schema
100
+ table_name = "sessions"
101
+ table_names = inspector.get_table_names(schema=schema)
102
+ if table_name not in table_names:
103
+ return False
104
+ columns = inspector.get_columns(table_name, schema=schema)
105
+ for column in columns:
106
+ if column["name"] == "param_data":
107
+ return "JSON" not in str(column["type"]).upper()
108
+ return False
109
+
96
110
  async with self._engine.begin() as conn:
111
+ if await conn.run_sync(_check_migration_needed):
112
+ await self._migrate_pickle_to_json()
113
+ return
97
114
  await conn.run_sync(Base.metadata.create_all)
98
115
 
99
116
  async def drop_tables(self) -> None:
@@ -104,6 +121,55 @@ class SessionDataManagerSQL(SessionDataManager):
104
121
  async def close(self) -> None:
105
122
  """Close any underlying connections."""
106
123
 
124
+ async def _migrate_pickle_to_json(self) -> None:
125
+ """Migrate param_data from pickle to JSON."""
126
+ schema = self.SessionConfig.__table__.schema
127
+ table_name = f"{schema}.sessions" if schema else "sessions"
128
+ json_type = "JSON"
129
+
130
+ async with self._engine.begin() as conn:
131
+ await conn.execute(
132
+ text(
133
+ f"ALTER TABLE {table_name} RENAME COLUMN param_data TO param_data_blob"
134
+ )
135
+ )
136
+ await conn.execute(
137
+ text(f"ALTER TABLE {table_name} ADD COLUMN param_data {json_type}")
138
+ )
139
+
140
+ result = await conn.execute(
141
+ text(f"SELECT session_key, param_data_blob FROM {table_name}")
142
+ )
143
+
144
+ for session_key, blob_data in result:
145
+ if not blob_data:
146
+ continue
147
+ try:
148
+ obj = pickle.loads(blob_data)
149
+ if hasattr(obj, "model_dump"):
150
+ json_data = obj.model_dump(mode="json")
151
+ elif hasattr(obj, "dict"):
152
+ json_data = obj.dict()
153
+ else:
154
+ json_data = obj.__dict__
155
+
156
+ val = json.dumps(json_data, default=str)
157
+
158
+ await conn.execute(
159
+ text(
160
+ f"UPDATE {table_name} SET param_data = :val WHERE session_key = :key"
161
+ ),
162
+ {"val": val, "key": session_key},
163
+ )
164
+ except Exception as exc:
165
+ raise RuntimeError(
166
+ f"Error migrating session {session_key}"
167
+ ) from exc
168
+
169
+ await conn.execute(
170
+ text(f"ALTER TABLE {table_name} DROP COLUMN param_data_blob")
171
+ )
172
+
107
173
  async def create_new_session(
108
174
  self,
109
175
  session_key: str,
@@ -113,10 +179,13 @@ class SessionDataManagerSQL(SessionDataManager):
113
179
  metadata: dict[str, object],
114
180
  ) -> None:
115
181
  """Create a new session entry in the database."""
116
- buffer = io.BytesIO()
117
- pickle.dump(param, buffer)
118
- buffer.seek(0)
119
- param_data = buffer.getvalue()
182
+ if hasattr(param, "model_dump"):
183
+ param_data = param.model_dump(mode="json")
184
+ elif hasattr(param, "dict"):
185
+ param_data = param.dict()
186
+ else:
187
+ param_data = param.__dict__
188
+
120
189
  async with self._async_session() as dbsession:
121
190
  # Query for an existing session with the same ID
122
191
  sessions = await dbsession.execute(
@@ -164,9 +233,7 @@ class SessionDataManagerSQL(SessionDataManager):
164
233
  session = sessions.scalars().first()
165
234
  if session is None:
166
235
  return None
167
- binary_buffer = io.BytesIO(session.param_data)
168
- binary_buffer.seek(0)
169
- param: EpisodicMemoryConf = pickle.load(binary_buffer)
236
+ param = EpisodicMemoryConf(**session.param_data)
170
237
 
171
238
  return SessionDataManager.SessionInfo(
172
239
  configuration=session.configuration,
@@ -557,9 +557,8 @@ class Neo4jVectorGraphStore(VectorGraphStore):
557
557
  )
558
558
  await self._driver.execute_query(
559
559
  "UNWIND $edges AS edge\n"
560
- "MATCH"
561
- f" (source:{sanitized_source_collection} {{uid: edge.source_uid}}),"
562
- f" (target:{sanitized_target_collection} {{uid: edge.target_uid}})\n"
560
+ f"MATCH (source:{sanitized_source_collection} {{uid: edge.source_uid}})\n"
561
+ f"MATCH (target:{sanitized_target_collection} {{uid: edge.target_uid}})\n"
563
562
  "CREATE (source)"
564
563
  f" -[r:{sanitized_relation} {{uid: edge.uid}}]->"
565
564
  " (target)\n"
@@ -306,6 +306,39 @@ class DeclarativeMemory:
306
306
  list[Episode]:
307
307
  A list of episodes relevant to the query, ordered chronologically.
308
308
 
309
+ """
310
+ scored_episodes = await self.search_scored(
311
+ query,
312
+ max_num_episodes=max_num_episodes,
313
+ property_filter=property_filter,
314
+ )
315
+ return [episode for _, episode in scored_episodes]
316
+
317
+ async def search_scored(
318
+ self,
319
+ query: str,
320
+ *,
321
+ max_num_episodes: int = 20,
322
+ property_filter: FilterExpr | None = None,
323
+ ) -> list[tuple[float, Episode]]:
324
+ """
325
+ Search declarative memory for episodes relevant to the query, returning scored episodes.
326
+
327
+ Args:
328
+ query (str):
329
+ The search query.
330
+ max_num_episodes (int):
331
+ The maximum number of episodes to return
332
+ (default: 20).
333
+ property_filter (FilterExpr | None):
334
+ Filterable property keys and values
335
+ to use for filtering episodes
336
+ (default: None).
337
+
338
+ Returns:
339
+ list[tuple[float, Episode]]:
340
+ A list of scored episodes relevant to the query, ordered chronologically.
341
+
309
342
  """
310
343
  mangled_property_filter = DeclarativeMemory._mangle_property_filter(
311
344
  property_filter,
@@ -377,9 +410,9 @@ class DeclarativeMemory:
377
410
  episode_contexts,
378
411
  )
379
412
 
380
- reranked_anchored_episode_contexts = [
381
- (nuclear_episode, episode_context)
382
- for _, nuclear_episode, episode_context in sorted(
413
+ reranked_scored_anchored_episode_contexts = [
414
+ (episode_context_score, nuclear_episode, episode_context)
415
+ for episode_context_score, nuclear_episode, episode_context in sorted(
383
416
  zip(
384
417
  episode_context_scores,
385
418
  nuclear_episodes,
@@ -392,11 +425,13 @@ class DeclarativeMemory:
392
425
  ]
393
426
 
394
427
  # Unify episode contexts.
395
- unified_episode_context = DeclarativeMemory._unify_anchored_episode_contexts(
396
- reranked_anchored_episode_contexts,
397
- max_num_episodes=max_num_episodes,
428
+ unified_scored_episode_context = (
429
+ DeclarativeMemory._unify_scored_anchored_episode_contexts(
430
+ reranked_scored_anchored_episode_contexts,
431
+ max_num_episodes=max_num_episodes,
432
+ )
398
433
  )
399
- return unified_episode_context
434
+ return unified_scored_episode_context
400
435
 
401
436
  async def _contextualize_episode(
402
437
  self,
@@ -569,21 +604,29 @@ class DeclarativeMemory:
569
604
  await asyncio.gather(*delete_nodes_tasks)
570
605
 
571
606
  @staticmethod
572
- def _unify_anchored_episode_contexts(
573
- anchored_episode_contexts: Iterable[tuple[Episode, Iterable[Episode]]],
607
+ def _unify_scored_anchored_episode_contexts(
608
+ scored_anchored_episode_contexts: Iterable[
609
+ tuple[float, Episode, Iterable[Episode]]
610
+ ],
574
611
  max_num_episodes: int,
575
- ) -> list[Episode]:
612
+ ) -> list[tuple[float, Episode]]:
576
613
  """Unify anchored episode contexts into a single list within the limit."""
577
- episode_set: set[Episode] = set()
614
+ episode_scores: dict[Episode, float] = {}
578
615
 
579
- for nuclear_episode, context in anchored_episode_contexts:
616
+ for score, nuclear_episode, context in scored_anchored_episode_contexts:
580
617
  context = list(context)
581
618
 
582
- if len(episode_set) >= max_num_episodes:
619
+ if len(episode_scores) >= max_num_episodes:
583
620
  break
584
- if (len(episode_set) + len(context)) <= max_num_episodes:
621
+ if (len(episode_scores) + len(context)) <= max_num_episodes:
585
622
  # It is impossible that the context exceeds the limit.
586
- episode_set.update(context)
623
+ episode_scores.update(
624
+ {
625
+ episode: score
626
+ for episode in context
627
+ if episode not in episode_scores
628
+ }
629
+ )
587
630
  else:
588
631
  # It is possible that the context exceeds the limit.
589
632
  # Prioritize episodes near the nuclear episode.
@@ -603,15 +646,15 @@ class DeclarativeMemory:
603
646
  # Add episodes to unified context until limit is reached,
604
647
  # or until the context is exhausted.
605
648
  for episode in nuclear_context:
606
- if len(episode_set) >= max_num_episodes:
649
+ if len(episode_scores) >= max_num_episodes:
607
650
  break
608
- episode_set.add(episode)
651
+ episode_scores.setdefault(episode, score)
609
652
 
610
653
  unified_episode_context = sorted(
611
- episode_set,
612
- key=lambda episode: (
613
- episode.timestamp,
614
- episode.uid,
654
+ [(score, episode) for episode, score in episode_scores.items()],
655
+ key=lambda scored_episode: (
656
+ scored_episode[1].timestamp,
657
+ scored_episode[1].uid,
615
658
  ),
616
659
  )
617
660
 
@@ -305,7 +305,9 @@ class EpisodicMemory:
305
305
  async def query_memory(
306
306
  self,
307
307
  query: str,
308
+ *,
308
309
  limit: int | None = None,
310
+ score_threshold: float = -float("inf"),
309
311
  property_filter: FilterExpr | None = None,
310
312
  ) -> QueryResponse | None:
311
313
  """
@@ -320,6 +322,7 @@ class EpisodicMemory:
320
322
  limit: The maximum number of episodes to return. The limit is
321
323
  applied to both short and long term memories. The default
322
324
  value is 20.
325
+ score_threshold: Minimum score to consider a match.
323
326
  property_filter: Properties to filter declarative memory searches.
324
327
 
325
328
  Returns:
@@ -336,9 +339,12 @@ class EpisodicMemory:
336
339
  if self._short_term_memory is None:
337
340
  short_episode: list[Episode] = []
338
341
  short_summary = ""
339
- long_episode = await cast("LongTermMemory", self._long_term_memory).search(
342
+ scored_long_episodes = await cast(
343
+ "LongTermMemory", self._long_term_memory
344
+ ).search_scored(
340
345
  query,
341
346
  num_episodes_limit=search_limit,
347
+ score_threshold=score_threshold,
342
348
  property_filter=property_filter,
343
349
  )
344
350
  elif self._long_term_memory is None:
@@ -349,19 +355,20 @@ class EpisodicMemory:
349
355
  filters=property_filter,
350
356
  )
351
357
  )
352
- long_episode = []
358
+ scored_long_episodes = []
353
359
  short_episode, short_summary = session_result
354
360
  else:
355
361
  # Concurrently search both memory stores
356
- session_result, long_episode = await asyncio.gather(
362
+ session_result, scored_long_episodes = await asyncio.gather(
357
363
  self._short_term_memory.get_short_term_memory_context(
358
364
  query,
359
365
  limit=search_limit,
360
366
  filters=property_filter,
361
367
  ),
362
- self._long_term_memory.search(
368
+ self._long_term_memory.search_scored(
363
369
  query,
364
370
  num_episodes_limit=search_limit,
371
+ score_threshold=score_threshold,
365
372
  property_filter=property_filter,
366
373
  ),
367
374
  )
@@ -371,11 +378,11 @@ class EpisodicMemory:
371
378
  # short-term memory
372
379
  episode_uid_set = {episode.uid for episode in short_episode}
373
380
 
374
- unique_long_episodes = []
375
- for episode in long_episode:
381
+ unique_scored_long_episodes = []
382
+ for score, episode in scored_long_episodes:
376
383
  if episode.uid not in episode_uid_set:
377
384
  episode_uid_set.add(episode.uid)
378
- unique_long_episodes.append(episode)
385
+ unique_scored_long_episodes.append((score, episode))
379
386
 
380
387
  end_time = time.monotonic_ns()
381
388
  delta = (end_time - start_time) / 1000000
@@ -391,8 +398,8 @@ class EpisodicMemory:
391
398
  ),
392
399
  long_term_memory=EpisodicMemory.QueryResponse.LongTermMemoryResponse(
393
400
  episodes=[
394
- EpisodeResponse(**episode.model_dump())
395
- for episode in unique_long_episodes
401
+ EpisodeResponse(score=score, **episode.model_dump())
402
+ for score, episode in unique_scored_long_episodes
396
403
  ],
397
404
  ),
398
405
  )
@@ -401,6 +408,7 @@ class EpisodicMemory:
401
408
  self,
402
409
  query: str,
403
410
  limit: int | None = None,
411
+ score_threshold: float = -float("inf"),
404
412
  property_filter: FilterExpr | None = None,
405
413
  ) -> str:
406
414
  """
@@ -412,6 +420,7 @@ class EpisodicMemory:
412
420
  Args:
413
421
  query: The original query string.
414
422
  limit: The maximum number of episodes to include in the context.
423
+ score_threshold: Minimum score to include in the context.
415
424
  property_filter: Properties to filter the search.
416
425
 
417
426
  Returns:
@@ -420,8 +429,9 @@ class EpisodicMemory:
420
429
  """
421
430
  query_result = await self.query_memory(
422
431
  query,
423
- limit,
424
- property_filter,
432
+ limit=limit,
433
+ score_threshold=score_threshold,
434
+ property_filter=property_filter,
425
435
  )
426
436
  if query_result is None:
427
437
  logger.warning("Query result is None in formalize_query_with_context")
@@ -139,18 +139,45 @@ class LongTermMemory:
139
139
  query: str,
140
140
  *,
141
141
  num_episodes_limit: int,
142
+ score_threshold: float = -float("inf"),
142
143
  property_filter: FilterExpr | None = None,
143
144
  ) -> list[Episode]:
144
- declarative_memory_episodes = await self._declarative_memory.search(
145
+ scored_episodes = await self.search_scored(
145
146
  query,
146
- max_num_episodes=num_episodes_limit,
147
- property_filter=LongTermMemory._sanitize_property_filter(property_filter),
147
+ num_episodes_limit=num_episodes_limit,
148
+ score_threshold=score_threshold,
149
+ property_filter=property_filter,
150
+ )
151
+ return [episode for _, episode in scored_episodes]
152
+
153
+ async def search_scored(
154
+ self,
155
+ query: str,
156
+ *,
157
+ num_episodes_limit: int,
158
+ score_threshold: float = -float("inf"),
159
+ property_filter: FilterExpr | None = None,
160
+ ) -> list[tuple[float, Episode]]:
161
+ scored_declarative_memory_episodes = (
162
+ await self._declarative_memory.search_scored(
163
+ query,
164
+ max_num_episodes=num_episodes_limit,
165
+ property_filter=LongTermMemory._sanitize_property_filter(
166
+ property_filter
167
+ ),
168
+ )
148
169
  )
149
170
  return [
150
- LongTermMemory._episode_from_declarative_memory_episode(
151
- declarative_memory_episode,
171
+ (
172
+ score,
173
+ LongTermMemory._episode_from_declarative_memory_episode(
174
+ declarative_memory_episode,
175
+ ),
152
176
  )
153
- for declarative_memory_episode in declarative_memory_episodes
177
+ for score, declarative_memory_episode in (
178
+ scored_declarative_memory_episodes
179
+ )
180
+ if score >= score_threshold
154
181
  ]
155
182
 
156
183
  async def get_episodes(self, uids: Iterable[str]) -> list[Episode]:
@@ -309,6 +309,7 @@ class MemMachine:
309
309
  session_data: InstanceOf[SessionData],
310
310
  query: str,
311
311
  limit: int | None = None,
312
+ score_threshold: float = -float("inf"),
312
313
  search_filter: FilterExpr | None = None,
313
314
  ) -> EpisodicMemory.QueryResponse | None:
314
315
  episodic_memory_manager = await self._resources.get_episodic_memory_manager()
@@ -324,6 +325,7 @@ class MemMachine:
324
325
  response = await episodic_session.query_memory(
325
326
  query=query,
326
327
  limit=limit,
328
+ score_threshold=score_threshold,
327
329
  property_filter=search_filter,
328
330
  )
329
331
 
@@ -337,6 +339,7 @@ class MemMachine:
337
339
  query: str,
338
340
  limit: int
339
341
  | None = None, # TODO: Define if limit is per memory or is global limit
342
+ score_threshold: float = -float("inf"),
340
343
  search_filter: str | None = None,
341
344
  ) -> SearchResponse:
342
345
  episodic_task: Task | None = None
@@ -349,6 +352,7 @@ class MemMachine:
349
352
  session_data=session_data,
350
353
  query=query,
351
354
  limit=limit,
355
+ score_threshold=score_threshold,
352
356
  search_filter=property_filter,
353
357
  )
354
358
  )
@@ -325,6 +325,7 @@ class Memory:
325
325
  self,
326
326
  query: str,
327
327
  limit: int | None = None,
328
+ score_threshold: float | None = None,
328
329
  filter_dict: dict[str, str] | None = None,
329
330
  timeout: int | None = None,
330
331
  ) -> SearchResult:
@@ -339,6 +340,7 @@ class Memory:
339
340
  Args:
340
341
  query: Search query string
341
342
  limit: Maximum number of results to return
343
+ score_threshold: Minimum score to include in results.
342
344
  filter_dict: Additional filters for the search (key-value pairs as strings).
343
345
  These filters will be merged with built-in filters from metadata.
344
346
  User-provided filters take precedence over built-in filters
@@ -377,6 +379,7 @@ class Memory:
377
379
  project_id=self.__project_id,
378
380
  query=query,
379
381
  top_k=limit or 10,
382
+ score_threshold=score_threshold,
380
383
  filter=filter_str,
381
384
  types=[MemoryType.Episodic, MemoryType.Semantic], # Search both types
382
385
  )
@@ -0,0 +1,28 @@
1
+ """${message}
2
+
3
+ Revision ID: ${up_revision}
4
+ Revises: ${down_revision | comma,n}
5
+ Create Date: ${create_date}
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+ ${imports if imports else ""}
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = ${repr(up_revision)}
16
+ down_revision: Union[str, Sequence[str], None] = ${repr(down_revision)}
17
+ branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
18
+ depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Upgrade schema."""
23
+ ${upgrades if upgrades else "pass"}
24
+
25
+
26
+ def downgrade() -> None:
27
+ """Downgrade schema."""
28
+ ${downgrades if downgrades else "pass"}