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.
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/PKG-INFO +8 -1
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/README.md +7 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/pyproject.toml +5 -2
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/__init__.py +1 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/api/doc.py +5 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/api/spec.py +8 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/episode_store/episode_model.py +1 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/session_manager/session_data_manager_sql_impl.py +79 -12
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/vector_graph_store/neo4j_vector_graph_store.py +2 -3
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/declarative_memory/declarative_memory.py +64 -21
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/episodic_memory.py +21 -11
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/long_term_memory/long_term_memory.py +33 -6
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/main/memmachine.py +4 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/rest_client/memory.py +3 -0
- memmachine_server-0.2.3/src/memmachine/semantic_memory/storage/alembic_pg/script.py.mako +28 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/api_v2/mcp.py +4 -1
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/api_v2/router.py +9 -36
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/api_v2/service.py +35 -2
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/app.py +42 -13
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/.gitignore +30 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/.prettierignore +18 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/.prettierrc +15 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/README.md +156 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/eslint.config.mjs +19 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/jest.config.ts +20 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/package-lock.json +10073 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/package.json +93 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/client/index.ts +9 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/client/memmachine-client.ts +118 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/client/memmachine-client.types.ts +34 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/env.d.ts +1 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/errors/api-error-handler.ts +20 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/errors/index.ts +8 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/errors/memmachine-api-error.ts +14 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/index.ts +13 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/memory/index.ts +20 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/memory/memmachine-memory.ts +315 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/memory/memmachine-memory.types.ts +166 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/project/index.ts +9 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/project/memmachine-project.ts +167 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/project/memmachine-project.types.ts +41 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/src/version.ts +1 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/tests/api-error-handler.spec.ts +36 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/tests/index.spec.ts +11 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/tests/memmachine-client.spec.ts +52 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/tests/memmachine-memory.spec.ts +149 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/tests/memmachine-project.spec.ts +101 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/tsconfig.json +44 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/tsup.config.ts +14 -0
- memmachine_server-0.2.3/src/memmachine-ts/rest_client/typedoc.json +4 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine_server.egg-info/PKG-INFO +8 -1
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine_server.egg-info/SOURCES.txt +32 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/LICENSE +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/setup.cfg +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/api/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/database_conf.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/default_episode_summary_system_prompt.txt +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/default_episode_summary_user_prompt.txt +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/embedder_conf.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/episodic_config.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/language_model_conf.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/log_conf.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/mixin_confs.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/configuration/reranker_conf.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/data_types.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/embedder/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/embedder/amazon_bedrock_embedder.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/embedder/embedder.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/embedder/openai_embedder.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/embedder/sentence_transformer_embedder.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/episode_store/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/episode_store/count_caching_episode_storage.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/episode_store/episode_sqlalchemy_store.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/episode_store/episode_storage.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/errors.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/filter/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/filter/filter_parser.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/filter/sql_filter_util.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/language_model/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/language_model/amazon_bedrock_language_model.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/language_model/language_model.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/language_model/openai_chat_completions_language_model.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/language_model/openai_responses_language_model.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/metrics_factory/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/metrics_factory/metrics_factory.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/metrics_factory/prometheus_metrics_factory.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/amazon_bedrock_reranker.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/bm25_reranker.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/cohere_reranker.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/cross_encoder_reranker.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/embedder_reranker.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/identity_reranker.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/reranker.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/reranker/rrf_hybrid_reranker.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/resource_manager/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/resource_manager/database_manager.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/resource_manager/embedder_manager.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/resource_manager/language_model_manager.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/resource_manager/reranker_manager.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/resource_manager/resource_manager.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/resource_manager/semantic_manager.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/session_manager/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/session_manager/session_data_manager.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/utils.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/vector_graph_store/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/vector_graph_store/data_types.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/common/vector_graph_store/vector_graph_store.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/declarative_memory/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/declarative_memory/data_types.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/episodic_memory_manager.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/instance_lru_cache.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/long_term_memory/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/long_term_memory/service_locator.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/service_locator.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/short_term_memory/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/short_term_memory/service_locator.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/episodic_memory/short_term_memory/short_term_memory.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/installation/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/installation/configuration_wizard.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/installation/memmachine_configure.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/installation/utilities.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/main/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/rest_client/README.md +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/rest_client/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/rest_client/client.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/rest_client/project.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/semantic_ingestion.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/semantic_llm.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/semantic_memory.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/semantic_model.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/semantic_session_manager.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/alembic_pg/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/alembic_pg/env.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/alembic_pg/versions/001_initial_migration.py +0 -0
- {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
- {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
- {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
- {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
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/alembic_pg/versions/__init__.py +0 -0
- {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
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/neo4j_semantic_storage.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/sqlalchemy_pgvector_semantic.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/storage/storage_base.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/util/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/semantic_memory/util/semantic_prompt_template.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/api_v2/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/mcp_http.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/mcp_stdio.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/__init__.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/coding_style_prompt.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/crm_prompt.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/default_prompts.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/financial_analyst_prompt.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/health_assistant_prompt.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/profile_prompt.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/prompt_utilities.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine/server/prompt/writing_assistant_prompt.py +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine_server.egg-info/dependency_links.txt +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine_server.egg-info/entry_points.txt +0 -0
- {memmachine_server-0.2.2 → memmachine_server-0.2.3}/src/memmachine_server.egg-info/requires.txt +0 -0
- {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.
|
|
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
|
+

|
|
46
47
|

|
|
47
48
|
[](https://deepwiki.com/MemMachine/MemMachine)
|
|
48
49
|

|
|
50
|
+
<br/>
|
|
51
|
+

|
|
52
|
+

|
|
53
|
+
<br/>
|
|
54
|
+

|
|
55
|
+

|
|
49
56
|
|
|
50
57
|
</div>
|
|
51
58
|
|
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
|
|
5
|
+

|
|
5
6
|

|
|
6
7
|
[](https://deepwiki.com/MemMachine/MemMachine)
|
|
7
8
|

|
|
9
|
+
<br/>
|
|
10
|
+

|
|
11
|
+

|
|
12
|
+
<br/>
|
|
13
|
+

|
|
14
|
+

|
|
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
|
-
|
|
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 = "../.."
|
|
@@ -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(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Manages database for session config and short term data."""
|
|
2
2
|
|
|
3
|
-
import
|
|
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[
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
|
|
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"
|
|
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
|
-
|
|
381
|
-
(nuclear_episode, episode_context)
|
|
382
|
-
for
|
|
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
|
-
|
|
396
|
-
|
|
397
|
-
|
|
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
|
|
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
|
|
573
|
-
|
|
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
|
-
|
|
614
|
+
episode_scores: dict[Episode, float] = {}
|
|
578
615
|
|
|
579
|
-
for nuclear_episode, context in
|
|
616
|
+
for score, nuclear_episode, context in scored_anchored_episode_contexts:
|
|
580
617
|
context = list(context)
|
|
581
618
|
|
|
582
|
-
if len(
|
|
619
|
+
if len(episode_scores) >= max_num_episodes:
|
|
583
620
|
break
|
|
584
|
-
if (len(
|
|
621
|
+
if (len(episode_scores) + len(context)) <= max_num_episodes:
|
|
585
622
|
# It is impossible that the context exceeds the limit.
|
|
586
|
-
|
|
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(
|
|
649
|
+
if len(episode_scores) >= max_num_episodes:
|
|
607
650
|
break
|
|
608
|
-
|
|
651
|
+
episode_scores.setdefault(episode, score)
|
|
609
652
|
|
|
610
653
|
unified_episode_context = sorted(
|
|
611
|
-
|
|
612
|
-
key=lambda
|
|
613
|
-
|
|
614
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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.
|
|
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
|
-
|
|
375
|
-
for episode in
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
145
|
+
scored_episodes = await self.search_scored(
|
|
145
146
|
query,
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
151
|
-
|
|
171
|
+
(
|
|
172
|
+
score,
|
|
173
|
+
LongTermMemory._episode_from_declarative_memory_episode(
|
|
174
|
+
declarative_memory_episode,
|
|
175
|
+
),
|
|
152
176
|
)
|
|
153
|
-
for declarative_memory_episode in
|
|
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"}
|