memmachine-server 0.3.2__tar.gz → 0.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {memmachine_server-0.3.2/src/memmachine_server.egg-info → memmachine_server-0.3.4}/PKG-INFO +1 -1
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/configuration/test_reranker_conf.py +33 -0
- memmachine_server-0.3.4/server_tests/memmachine_server/common/embedder/test_openai_embedder.py +126 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/language_model/test_openai_chat_completions_language_model.py +397 -1
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/language_model/test_openai_responses_language_model.py +32 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/resource_manager/test_reranker_manager.py +68 -1
- memmachine_server-0.3.4/server_tests/memmachine_server/common/test_rw_locks.py +214 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/episodic_memory/conftest.py +26 -8
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/episodic_memory/short_term_memory/test_short_term_memory.py +72 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/installation/test_memmachine_configure.py +116 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/main/test_memmachine_delete_session.py +4 -2
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/main/test_memmachine_mock.py +30 -27
- memmachine_server-0.3.4/server_tests/memmachine_server/semantic_memory/cluster_store/__init__.py +1 -0
- memmachine_server-0.3.4/server_tests/memmachine_server/semantic_memory/cluster_store/test_cluster_state_storage.py +346 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/mock_semantic_memory_objects.py +28 -17
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/storage/in_memory_semantic_storage.py +113 -53
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/storage/test_semantic_storage.py +330 -90
- memmachine_server-0.3.4/server_tests/memmachine_server/semantic_memory/storage/test_text_sanitizer.py +48 -0
- memmachine_server-0.3.4/server_tests/memmachine_server/semantic_memory/test_cluster_manager.py +268 -0
- memmachine_server-0.3.4/server_tests/memmachine_server/semantic_memory/test_cluster_splitter.py +477 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/test_semantic_history_cleanup.py +6 -2
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/test_semantic_ingestion.py +175 -40
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/test_semantic_memory.py +53 -27
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/test_semantic_memory_background.py +15 -5
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/test_semantic_memory_integration.py +12 -5
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/test_semantic_model.py +93 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/test_semantic_session_manager.py +69 -42
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/configuration/__init__.py +9 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/configuration/mixin_confs.py +16 -7
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/configuration/reranker_conf.py +16 -1
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/data_types.py +5 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/embedder/openai_embedder.py +18 -1
- memmachine_server-0.3.4/src/memmachine_server/common/language_model/openai_chat_completions_language_model.py +548 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/language_model/openai_responses_language_model.py +4 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/resource_manager/database_manager.py +1 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/resource_manager/reranker_manager.py +4 -1
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/resource_manager/semantic_manager.py +1 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/rw_locks.py +1 -70
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/utils.py +58 -1
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/vector_graph_store/nebula_graph_vector_graph_store.py +53 -8
- memmachine_server-0.3.4/src/memmachine_server/common/vector_store/__init__.py +20 -0
- memmachine_server-0.3.4/src/memmachine_server/common/vector_store/data_types.py +168 -0
- memmachine_server-0.3.4/src/memmachine_server/common/vector_store/utils.py +47 -0
- memmachine_server-0.3.4/src/memmachine_server/common/vector_store/vector_store.py +272 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/episodic_memory/episodic_memory_manager.py +12 -9
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/episodic_memory/short_term_memory/short_term_memory.py +44 -20
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/installation/memmachine_configure.py +48 -5
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/main/memmachine.py +28 -18
- memmachine_server-0.3.4/src/memmachine_server/semantic_memory/cluster_manager.py +210 -0
- memmachine_server-0.3.4/src/memmachine_server/semantic_memory/cluster_splitter.py +521 -0
- memmachine_server-0.3.4/src/memmachine_server/semantic_memory/cluster_store/__init__.py +1 -0
- memmachine_server-0.3.4/src/memmachine_server/semantic_memory/cluster_store/cluster_store.py +23 -0
- memmachine_server-0.3.4/src/memmachine_server/semantic_memory/cluster_store/cluster_store_sqlalchemy.py +285 -0
- memmachine_server-0.3.4/src/memmachine_server/semantic_memory/cluster_store/in_memory_cluster_store.py +38 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/config_store/caching_semantic_config_storage.py +33 -13
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/semantic_ingestion.py +70 -18
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/semantic_llm.py +8 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/semantic_memory.py +127 -78
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/semantic_model.py +22 -13
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/semantic_session_manager.py +35 -25
- memmachine_server-0.3.4/src/memmachine_server/semantic_memory/storage/alembic_pg/versions/c7a2f8e31b90_add_ingested_composite_index.py +36 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/neo4j_semantic_storage.py +203 -120
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/sqlalchemy_pgvector_semantic.py +148 -89
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/storage_base.py +33 -17
- memmachine_server-0.3.4/src/memmachine_server/semantic_memory/storage/text_sanitizer.py +22 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/util/semantic_prompt_template.py +4 -2
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/api_v2/router.py +8 -4
- {memmachine_server-0.3.2 → memmachine_server-0.3.4/src/memmachine_server.egg-info}/PKG-INFO +1 -1
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server.egg-info/SOURCES.txt +14 -0
- memmachine_server-0.3.2/server_tests/memmachine_server/common/embedder/test_openai_embedder.py +0 -48
- memmachine_server-0.3.2/server_tests/memmachine_server/common/test_rw_locks.py +0 -393
- memmachine_server-0.3.2/src/memmachine_server/common/language_model/openai_chat_completions_language_model.py +0 -318
- memmachine_server-0.3.2/src/memmachine_server/common/vector_store/__init__.py +0 -11
- memmachine_server-0.3.2/src/memmachine_server/common/vector_store/data_types.py +0 -37
- memmachine_server-0.3.2/src/memmachine_server/common/vector_store/vector_store.py +0 -193
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/LICENSE +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/README.md +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/pyproject.toml +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/api/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/api/test_version.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/configuration/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/configuration/test_configuration.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/configuration/test_database_conf.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/configuration/test_embedder_conf.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/configuration/test_episodic_config.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/configuration/test_language_model_conf.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/configuration/test_log_conf.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/configuration/test_mixin_confs.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/configuration/test_prompt_conf.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/configuration/test_semantic_conf.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/configuration/test_server_conf.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/embedder/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/embedder/test_amazon_bedrock_embedder.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/embedder/test_sentence_transformer_embedder.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/episode_store/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/episode_store/test_count_caching_episode_storage.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/episode_store/test_episode_model.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/episode_store/test_episode_storage.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/episode_store/test_sqlalchemy_episode_store_startup.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/filter/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/filter/test_filter_parser.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/filter/test_sql_filter_util.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/language_model/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/reranker/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/reranker/fake_embedder.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/reranker/test_amazon_bedrock_reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/reranker/test_bm25_reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/reranker/test_cohere_reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/reranker/test_cross_encoder_reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/reranker/test_embedder_reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/reranker/test_identity_reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/reranker/test_rrf_hybrid_reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/resource_manager/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/resource_manager/test_database_manager.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/resource_manager/test_embedder_manager.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/resource_manager/test_language_model_manager.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/resource_manager/test_resource_manager.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/session_manager/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/session_manager/test_session_manager.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/session_manager/test_session_manager_migration.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/test_utils.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/vector_graph_store/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/vector_graph_store/test_nebula_graph_vector_graph_store.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/common/vector_graph_store/test_neo4j_vector_graph_store.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/conftest.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/episodic_memory/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/episodic_memory/declarative_memory/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/episodic_memory/declarative_memory/test_declarative_memory.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/episodic_memory/long_term_memory/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/episodic_memory/long_term_memory/test_long_term_memory.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/episodic_memory/short_term_memory/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/episodic_memory/test_episodic_memory.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/episodic_memory/test_episodic_memory_manager.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/episodic_memory/test_instance_lru_cache.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/installation/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/installation/test_configuration_wizard.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/installation/test_utilities.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/main/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/main/conftest.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/main/test_memachine.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/main/test_memmachine_integration.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/retrieval_agent/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/retrieval_agent/test_retrieval_agent.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/config_store/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/config_store/test_caching_semantic_config_storage.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/config_store/test_semantic_config_storage.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/conftest.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/semantic_test_utils.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/storage/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/storage/alembic_pg/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/storage/alembic_pg/helpers.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/storage/alembic_pg/original_schema.sql +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/storage/alembic_pg/test_set_id_migration.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/storage/alembic_pg/test_sqlalchemy_vs_alembic.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/storage/conftest.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/test_semantic_llm.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/semantic_memory/test_semantic_llm_integration.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/server/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/server/api_v2/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/server/api_v2/test_config_router.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/server/api_v2/test_config_service.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/server/api_v2/test_mcp.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/server/api_v2/test_router.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/server/api_v2/test_service.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/server/api_v2/test_spec.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/server/prompt/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/server/prompt/test_prompt_utilities.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/server/test_middleware.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/server_tests/memmachine_server/test_data/longmemeval_snippet.json +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/setup.cfg +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/api/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/api/version.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/configuration/database_conf.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/configuration/default_episode_summary_system_prompt.txt +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/configuration/default_episode_summary_user_prompt.txt +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/configuration/embedder_conf.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/configuration/episodic_config.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/configuration/language_model_conf.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/configuration/log_conf.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/configuration/retrieval_config.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/embedder/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/embedder/amazon_bedrock_embedder.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/embedder/embedder.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/embedder/sentence_transformer_embedder.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/episode_store/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/episode_store/count_caching_episode_storage.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/episode_store/episode_model.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/episode_store/episode_sqlalchemy_store.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/episode_store/episode_storage.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/errors.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/filter/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/filter/filter_parser.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/filter/sql_filter_util.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/language_model/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/language_model/amazon_bedrock_language_model.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/language_model/language_model.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/metrics_factory/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/metrics_factory/metrics_factory.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/metrics_factory/operation_tracker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/metrics_factory/prometheus_metrics_factory.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/neo4j_utils.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/reranker/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/reranker/amazon_bedrock_reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/reranker/bm25_reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/reranker/cohere_reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/reranker/cross_encoder_reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/reranker/embedder_reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/reranker/identity_reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/reranker/reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/reranker/rrf_hybrid_reranker.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/resource_manager/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/resource_manager/base_manager.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/resource_manager/embedder_manager.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/resource_manager/language_model_manager.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/resource_manager/resource_manager.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/session_manager/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/session_manager/session_data_manager.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/session_manager/session_data_manager_sql_impl.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/vector_graph_store/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/vector_graph_store/data_types.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/vector_graph_store/neo4j_vector_graph_store.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/common/vector_graph_store/vector_graph_store.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/episodic_memory/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/episodic_memory/declarative_memory/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/episodic_memory/declarative_memory/data_types.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/episodic_memory/declarative_memory/declarative_memory.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/episodic_memory/episodic_memory.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/episodic_memory/instance_lru_cache.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/episodic_memory/long_term_memory/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/episodic_memory/long_term_memory/long_term_memory.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/episodic_memory/long_term_memory/service_locator.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/episodic_memory/service_locator.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/episodic_memory/short_term_memory/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/episodic_memory/short_term_memory/service_locator.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/installation/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/installation/configuration_wizard.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/installation/utilities.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/main/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/retrieval_agent/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/retrieval_agent/agents/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/retrieval_agent/agents/coq_agent.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/retrieval_agent/agents/memmachine_retriever.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/retrieval_agent/agents/split_query_agent.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/retrieval_agent/agents/tool_select_agent.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/retrieval_agent/common/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/retrieval_agent/common/agent_api.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/retrieval_agent/service_locator.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/config_store/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/config_store/config_store.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/config_store/config_store_sqlalchemy.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/alembic_pg/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/alembic_pg/env.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/alembic_pg/script.py.mako +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/alembic_pg/versions/001_initial_migration.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/alembic_pg/versions/3d6aaebdc526_sync_sqlalchemy_schema.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/alembic_pg/versions/62dff1150a46_add_created_at_to_history_add.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/alembic_pg/versions/79f00a9f2409_change_history_id_to_string.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/alembic_pg/versions/843f6d216d10_rename_semantic_type_to_semantic_.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/alembic_pg/versions/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/alembic_pg/versions/adb5618bd4ee_remove_history_table.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/alembic_pg/versions/b65f7f4a9d2c_migrate_legacy_set_ids.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/storage/alembic_pg/versions/d1a9df11343b_add_indexes.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/semantic_memory/util/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/api_v2/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/api_v2/config_router.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/api_v2/config_service.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/api_v2/exceptions.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/api_v2/mcp.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/api_v2/service.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/app.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/diagnostics.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/mcp_http.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/mcp_stdio.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/middleware.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/prompt/__init__.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/prompt/coding_style_prompt.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/prompt/crm_prompt.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/prompt/default_prompts.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/prompt/financial_analyst_prompt.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/prompt/health_assistant_prompt.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/prompt/profile_prompt.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/prompt/prompt_utilities.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server/server/prompt/writing_assistant_prompt.py +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server.egg-info/dependency_links.txt +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server.egg-info/entry_points.txt +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/src/memmachine_server.egg-info/requires.txt +0 -0
- {memmachine_server-0.3.2 → memmachine_server-0.3.4}/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.3.
|
|
3
|
+
Version: 0.3.4
|
|
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
|
|
@@ -7,6 +7,7 @@ from pydantic import SecretStr, ValidationError
|
|
|
7
7
|
from memmachine_server.common.configuration.reranker_conf import (
|
|
8
8
|
AmazonBedrockRerankerConf,
|
|
9
9
|
BM25RerankerConf,
|
|
10
|
+
CohereRerankerConf,
|
|
10
11
|
CrossEncoderRerankerConf,
|
|
11
12
|
EmbedderRerankerConf,
|
|
12
13
|
IdentityRerankerConf,
|
|
@@ -47,6 +48,18 @@ def amazon_bedrock_reranker_conf() -> dict:
|
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
|
|
51
|
+
@pytest.fixture
|
|
52
|
+
def cohere_reranker_conf() -> dict:
|
|
53
|
+
return {
|
|
54
|
+
"provider": "cohere",
|
|
55
|
+
"config": {
|
|
56
|
+
"cohere_key": "test-cohere-key",
|
|
57
|
+
"model": "rerank-english-v3.0",
|
|
58
|
+
"base_url": "http://localhost:8000",
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
50
63
|
@pytest.fixture
|
|
51
64
|
def cross_encoder_reranker_conf() -> dict:
|
|
52
65
|
return {
|
|
@@ -83,6 +96,7 @@ def full_reranker_input(
|
|
|
83
96
|
bm25_reranker_conf,
|
|
84
97
|
identity_reranker_conf,
|
|
85
98
|
amazon_bedrock_reranker_conf,
|
|
99
|
+
cohere_reranker_conf,
|
|
86
100
|
cross_encoder_reranker_conf,
|
|
87
101
|
embedder_reranker_conf,
|
|
88
102
|
rrf_hybrid_reranker_conf,
|
|
@@ -93,6 +107,7 @@ def full_reranker_input(
|
|
|
93
107
|
"id_ranker_id": identity_reranker_conf,
|
|
94
108
|
"bm_ranker_id": bm25_reranker_conf,
|
|
95
109
|
"aws_reranker_id": amazon_bedrock_reranker_conf,
|
|
110
|
+
"cohere_reranker_id": cohere_reranker_conf,
|
|
96
111
|
"cross_encoder_id": cross_encoder_reranker_conf,
|
|
97
112
|
"embedder_id": embedder_reranker_conf,
|
|
98
113
|
},
|
|
@@ -121,6 +136,13 @@ def test_valid_amazon_bedrock_reranker_conf(amazon_bedrock_reranker_conf):
|
|
|
121
136
|
assert conf.model_id == "amazon.rerank-v1:0"
|
|
122
137
|
|
|
123
138
|
|
|
139
|
+
def test_valid_cohere_reranker_conf(cohere_reranker_conf):
|
|
140
|
+
conf = CohereRerankerConf(**cohere_reranker_conf["config"])
|
|
141
|
+
assert conf.cohere_key == SecretStr("test-cohere-key")
|
|
142
|
+
assert conf.model == "rerank-english-v3.0"
|
|
143
|
+
assert conf.base_url == "http://localhost:8000"
|
|
144
|
+
|
|
145
|
+
|
|
124
146
|
def test_valid_cross_encoder_reranker_conf(cross_encoder_reranker_conf):
|
|
125
147
|
conf = CrossEncoderRerankerConf(**cross_encoder_reranker_conf["config"])
|
|
126
148
|
assert conf.model_name == "cross-encoder/qnli-electra-base"
|
|
@@ -150,6 +172,8 @@ def test_full_reranker_conf(full_reranker_input):
|
|
|
150
172
|
|
|
151
173
|
assert "aws_reranker_id" in conf.amazon_bedrock
|
|
152
174
|
assert conf.amazon_bedrock["aws_reranker_id"].region == "us-west-2"
|
|
175
|
+
assert "cohere_reranker_id" in conf.cohere
|
|
176
|
+
assert conf.cohere["cohere_reranker_id"].base_url == "http://localhost:8000"
|
|
153
177
|
|
|
154
178
|
assert "cross_encoder_id" in conf.cross_encoder
|
|
155
179
|
assert (
|
|
@@ -182,3 +206,12 @@ def test_missing_required_field_in_bedrock_reranker():
|
|
|
182
206
|
AmazonBedrockRerankerConf(**config)
|
|
183
207
|
assert "missing" in str(exc_info.value)
|
|
184
208
|
assert "aws_secret_access_key" in str(exc_info.value)
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def test_invalid_cohere_base_url():
|
|
212
|
+
with pytest.raises(ValidationError, match="Invalid base URL"):
|
|
213
|
+
CohereRerankerConf(
|
|
214
|
+
cohere_key=SecretStr("test-cohere-key"),
|
|
215
|
+
model="rerank-english-v3.0",
|
|
216
|
+
base_url="localhost:8000",
|
|
217
|
+
)
|
memmachine_server-0.3.4/server_tests/memmachine_server/common/embedder/test_openai_embedder.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
from unittest.mock import AsyncMock, MagicMock, patch
|
|
2
|
+
|
|
3
|
+
import openai
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from memmachine_server.common.data_types import ExternalServiceAPIError
|
|
7
|
+
from memmachine_server.common.embedder.openai_embedder import (
|
|
8
|
+
OpenAIEmbedder,
|
|
9
|
+
OpenAIEmbedderParams,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@pytest.fixture(
|
|
14
|
+
params=[
|
|
15
|
+
["Are tomatoes fruits?", "Tomatoes are red."],
|
|
16
|
+
["Are tomatoes fruits?", "Tomatoes are red.", ""],
|
|
17
|
+
["."],
|
|
18
|
+
[" "],
|
|
19
|
+
[""],
|
|
20
|
+
[],
|
|
21
|
+
],
|
|
22
|
+
)
|
|
23
|
+
def inputs(request):
|
|
24
|
+
return request.param
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@pytest.mark.integration
|
|
28
|
+
@pytest.mark.asyncio
|
|
29
|
+
async def test_ingest_embed(openai_embedder, inputs):
|
|
30
|
+
embeddings = await openai_embedder.ingest_embed(inputs)
|
|
31
|
+
assert isinstance(embeddings, list)
|
|
32
|
+
assert len(embeddings) == len(inputs)
|
|
33
|
+
assert all(len(embedding) == openai_embedder.dimensions for embedding in embeddings)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@pytest.mark.integration
|
|
37
|
+
@pytest.mark.asyncio
|
|
38
|
+
async def test_search_embed(openai_embedder, inputs):
|
|
39
|
+
embeddings = await openai_embedder.search_embed(inputs)
|
|
40
|
+
assert isinstance(embeddings, list)
|
|
41
|
+
assert len(embeddings) == len(inputs)
|
|
42
|
+
assert all(len(embedding) == openai_embedder.dimensions for embedding in embeddings)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@pytest.mark.integration
|
|
46
|
+
@pytest.mark.asyncio
|
|
47
|
+
async def test_large_input(openai_embedder):
|
|
48
|
+
input_text = "👩💻" * 10000
|
|
49
|
+
|
|
50
|
+
assert len(await openai_embedder.ingest_embed([input_text])) == 1
|
|
51
|
+
assert len(await openai_embedder.search_embed([input_text])) == 1
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@pytest.mark.integration
|
|
55
|
+
@pytest.mark.asyncio
|
|
56
|
+
async def test_many_inputs(openai_embedder):
|
|
57
|
+
input_texts = ["Hello, world!"] * 10000
|
|
58
|
+
assert len(await openai_embedder.ingest_embed(input_texts)) == 10000
|
|
59
|
+
assert len(await openai_embedder.search_embed(input_texts)) == 10000
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@pytest.mark.asyncio
|
|
63
|
+
@patch("asyncio.sleep", new_callable=AsyncMock)
|
|
64
|
+
async def test_embed_retry_on_internal_server_error(mock_sleep):
|
|
65
|
+
"""Test retry logic on InternalServerError."""
|
|
66
|
+
mock_client = AsyncMock(spec=openai.AsyncOpenAI)
|
|
67
|
+
|
|
68
|
+
mock_embedding = MagicMock()
|
|
69
|
+
mock_embedding.embedding = [0.1] * 256
|
|
70
|
+
|
|
71
|
+
mock_response = MagicMock()
|
|
72
|
+
mock_response.data = [mock_embedding]
|
|
73
|
+
mock_response.usage.prompt_tokens = 10
|
|
74
|
+
mock_response.usage.total_tokens = 10
|
|
75
|
+
|
|
76
|
+
mock_client.embeddings.create = AsyncMock(
|
|
77
|
+
side_effect=[
|
|
78
|
+
openai.InternalServerError(
|
|
79
|
+
"internal server error", response=MagicMock(), body=None
|
|
80
|
+
),
|
|
81
|
+
mock_response,
|
|
82
|
+
]
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
embedder = OpenAIEmbedder(
|
|
86
|
+
OpenAIEmbedderParams(
|
|
87
|
+
client=mock_client,
|
|
88
|
+
model="test-model",
|
|
89
|
+
dimensions=256,
|
|
90
|
+
)
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
result = await embedder.ingest_embed(["test input"], max_attempts=2)
|
|
94
|
+
|
|
95
|
+
assert len(result) == 1
|
|
96
|
+
assert len(result[0]) == 256
|
|
97
|
+
assert mock_client.embeddings.create.call_count == 2
|
|
98
|
+
mock_sleep.assert_awaited_once_with(1)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@pytest.mark.asyncio
|
|
102
|
+
@patch("asyncio.sleep", new_callable=AsyncMock)
|
|
103
|
+
async def test_embed_fail_after_max_retries_on_internal_server_error(mock_sleep):
|
|
104
|
+
"""Test that ExternalServiceAPIError is raised after max_attempts on InternalServerError."""
|
|
105
|
+
mock_client = AsyncMock(spec=openai.AsyncOpenAI)
|
|
106
|
+
mock_client.embeddings.create = AsyncMock(
|
|
107
|
+
side_effect=openai.InternalServerError(
|
|
108
|
+
"internal server error", response=MagicMock(), body=None
|
|
109
|
+
),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
embedder = OpenAIEmbedder(
|
|
113
|
+
OpenAIEmbedderParams(
|
|
114
|
+
client=mock_client,
|
|
115
|
+
model="test-model",
|
|
116
|
+
dimensions=256,
|
|
117
|
+
)
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
with pytest.raises(ExternalServiceAPIError, match=r"max attempts"):
|
|
121
|
+
await embedder.ingest_embed(["test input"], max_attempts=3)
|
|
122
|
+
|
|
123
|
+
assert mock_client.embeddings.create.call_count == 3
|
|
124
|
+
assert mock_sleep.call_count == 2
|
|
125
|
+
mock_sleep.assert_any_await(1)
|
|
126
|
+
mock_sleep.assert_any_await(2)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Unit tests for OpenAIChatCompletionsLanguageModel."""
|
|
2
2
|
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any, cast
|
|
3
5
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
4
6
|
|
|
5
7
|
import httpx
|
|
@@ -9,7 +11,7 @@ from openai.types import chat as openai_chat
|
|
|
9
11
|
from openai.types.chat.chat_completion_message_function_tool_call import (
|
|
10
12
|
Function as ToolCallFunction,
|
|
11
13
|
)
|
|
12
|
-
from pydantic import ValidationError
|
|
14
|
+
from pydantic import BaseModel, ValidationError
|
|
13
15
|
|
|
14
16
|
from memmachine_server.common.data_types import ExternalServiceAPIError
|
|
15
17
|
from memmachine_server.common.language_model.openai_chat_completions_language_model import (
|
|
@@ -19,6 +21,38 @@ from memmachine_server.common.language_model.openai_chat_completions_language_mo
|
|
|
19
21
|
from memmachine_server.common.metrics_factory import MetricsFactory
|
|
20
22
|
|
|
21
23
|
|
|
24
|
+
class FakeAsyncStream:
|
|
25
|
+
def __init__(self, chunks):
|
|
26
|
+
self._chunks = iter(chunks)
|
|
27
|
+
|
|
28
|
+
def __aiter__(self):
|
|
29
|
+
return self
|
|
30
|
+
|
|
31
|
+
async def __anext__(self):
|
|
32
|
+
try:
|
|
33
|
+
return next(self._chunks)
|
|
34
|
+
except StopIteration as exc:
|
|
35
|
+
raise StopAsyncIteration from exc
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class FakeReasoningChunk:
|
|
40
|
+
type: str = "response.reasoning.delta"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ParsedResponse(BaseModel):
|
|
44
|
+
answer: str
|
|
45
|
+
confidence: float
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def make_chat_completion(data: dict[str, Any]) -> openai_chat.ChatCompletion:
|
|
49
|
+
return openai_chat.ChatCompletion.model_validate(data)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def make_chat_completion_chunk(data: dict[str, Any]) -> openai_chat.ChatCompletionChunk:
|
|
53
|
+
return openai_chat.ChatCompletionChunk.model_validate(data)
|
|
54
|
+
|
|
55
|
+
|
|
22
56
|
@pytest.fixture
|
|
23
57
|
def mock_metrics_factory():
|
|
24
58
|
"""Fixture for a mocked MetricsFactory."""
|
|
@@ -213,6 +247,339 @@ async def test_generate_response_success(mock_async_openai, minimal_config):
|
|
|
213
247
|
{"role": "system", "content": "System prompt"},
|
|
214
248
|
{"role": "user", "content": "User prompt"},
|
|
215
249
|
]
|
|
250
|
+
assert call_args.kwargs["store"] is False
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
@pytest.mark.asyncio
|
|
254
|
+
async def test_generate_parsed_response_success(mock_async_openai, minimal_config):
|
|
255
|
+
"""Test a non-streamed structured response is parsed correctly."""
|
|
256
|
+
mock_response = make_chat_completion(
|
|
257
|
+
{
|
|
258
|
+
"id": "completion-1",
|
|
259
|
+
"object": "chat.completion",
|
|
260
|
+
"created": 1,
|
|
261
|
+
"model": "test-model",
|
|
262
|
+
"choices": [
|
|
263
|
+
{
|
|
264
|
+
"index": 0,
|
|
265
|
+
"finish_reason": "stop",
|
|
266
|
+
"message": {
|
|
267
|
+
"role": "assistant",
|
|
268
|
+
"content": '{"answer":"ok","confidence":0.9}',
|
|
269
|
+
"refusal": None,
|
|
270
|
+
},
|
|
271
|
+
}
|
|
272
|
+
],
|
|
273
|
+
"usage": {
|
|
274
|
+
"prompt_tokens": 7,
|
|
275
|
+
"completion_tokens": 5,
|
|
276
|
+
"total_tokens": 12,
|
|
277
|
+
},
|
|
278
|
+
}
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
mock_client = mock_async_openai.return_value
|
|
282
|
+
mock_client.chat.completions.create.return_value = mock_response
|
|
283
|
+
|
|
284
|
+
lm = OpenAIChatCompletionsLanguageModel(minimal_config)
|
|
285
|
+
parsed = await lm.generate_parsed_response(
|
|
286
|
+
ParsedResponse,
|
|
287
|
+
system_prompt="System prompt",
|
|
288
|
+
user_prompt="User prompt",
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
assert parsed == ParsedResponse(answer="ok", confidence=0.9)
|
|
292
|
+
call_args = mock_client.chat.completions.create.call_args
|
|
293
|
+
assert call_args.kwargs["model"] == "test-model"
|
|
294
|
+
assert call_args.kwargs["messages"] == [
|
|
295
|
+
{"role": "system", "content": "System prompt"},
|
|
296
|
+
{"role": "user", "content": "User prompt"},
|
|
297
|
+
]
|
|
298
|
+
assert call_args.kwargs["response_format"]["type"] == "json_schema"
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
@pytest.mark.asyncio
|
|
302
|
+
async def test_generate_parsed_response_from_stream(
|
|
303
|
+
mock_async_openai,
|
|
304
|
+
minimal_config,
|
|
305
|
+
):
|
|
306
|
+
"""Test a streamed structured response is aggregated and validated."""
|
|
307
|
+
streamed_response = FakeAsyncStream(
|
|
308
|
+
[
|
|
309
|
+
FakeReasoningChunk(),
|
|
310
|
+
make_chat_completion_chunk(
|
|
311
|
+
{
|
|
312
|
+
"id": "chunk-1",
|
|
313
|
+
"object": "chat.completion.chunk",
|
|
314
|
+
"created": 1,
|
|
315
|
+
"model": "test-model",
|
|
316
|
+
"choices": [
|
|
317
|
+
{
|
|
318
|
+
"index": 0,
|
|
319
|
+
"delta": {
|
|
320
|
+
"role": "assistant",
|
|
321
|
+
"content": '{"answer":"ok",',
|
|
322
|
+
},
|
|
323
|
+
"finish_reason": None,
|
|
324
|
+
"logprobs": None,
|
|
325
|
+
}
|
|
326
|
+
],
|
|
327
|
+
"usage": None,
|
|
328
|
+
}
|
|
329
|
+
),
|
|
330
|
+
make_chat_completion_chunk(
|
|
331
|
+
{
|
|
332
|
+
"id": "chunk-2",
|
|
333
|
+
"object": "chat.completion.chunk",
|
|
334
|
+
"created": 2,
|
|
335
|
+
"model": "test-model",
|
|
336
|
+
"choices": [
|
|
337
|
+
{
|
|
338
|
+
"index": 0,
|
|
339
|
+
"delta": {"content": '"confidence":0.9}'},
|
|
340
|
+
"finish_reason": "stop",
|
|
341
|
+
"logprobs": None,
|
|
342
|
+
}
|
|
343
|
+
],
|
|
344
|
+
"usage": None,
|
|
345
|
+
}
|
|
346
|
+
),
|
|
347
|
+
]
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
mock_client = mock_async_openai.return_value
|
|
351
|
+
mock_client.chat.completions.create.return_value = streamed_response
|
|
352
|
+
|
|
353
|
+
lm = OpenAIChatCompletionsLanguageModel(minimal_config)
|
|
354
|
+
parsed = await lm.generate_parsed_response(ParsedResponse)
|
|
355
|
+
|
|
356
|
+
assert parsed == ParsedResponse(answer="ok", confidence=0.9)
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
@pytest.mark.asyncio
|
|
360
|
+
async def test_generate_parsed_response_from_stream_discards_reasoning_delta_chunks(
|
|
361
|
+
mock_async_openai,
|
|
362
|
+
minimal_config,
|
|
363
|
+
):
|
|
364
|
+
"""Test streamed structured responses ignore chunks with reasoning_content."""
|
|
365
|
+
reasoning_chunk = make_chat_completion_chunk(
|
|
366
|
+
{
|
|
367
|
+
"id": "chunk-0",
|
|
368
|
+
"object": "chat.completion.chunk",
|
|
369
|
+
"created": 0,
|
|
370
|
+
"model": "test-model",
|
|
371
|
+
"choices": [
|
|
372
|
+
{
|
|
373
|
+
"index": 0,
|
|
374
|
+
"delta": {"content": None},
|
|
375
|
+
"finish_reason": None,
|
|
376
|
+
"logprobs": None,
|
|
377
|
+
}
|
|
378
|
+
],
|
|
379
|
+
"usage": None,
|
|
380
|
+
}
|
|
381
|
+
)
|
|
382
|
+
cast(Any, reasoning_chunk.choices[0].delta).reasoning_content = "chain-of-thought"
|
|
383
|
+
|
|
384
|
+
streamed_response = FakeAsyncStream(
|
|
385
|
+
[
|
|
386
|
+
reasoning_chunk,
|
|
387
|
+
make_chat_completion_chunk(
|
|
388
|
+
{
|
|
389
|
+
"id": "chunk-1",
|
|
390
|
+
"object": "chat.completion.chunk",
|
|
391
|
+
"created": 1,
|
|
392
|
+
"model": "test-model",
|
|
393
|
+
"choices": [
|
|
394
|
+
{
|
|
395
|
+
"index": 0,
|
|
396
|
+
"delta": {
|
|
397
|
+
"role": "assistant",
|
|
398
|
+
"content": '{"answer":"ok",',
|
|
399
|
+
},
|
|
400
|
+
"finish_reason": None,
|
|
401
|
+
"logprobs": None,
|
|
402
|
+
}
|
|
403
|
+
],
|
|
404
|
+
"usage": None,
|
|
405
|
+
}
|
|
406
|
+
),
|
|
407
|
+
make_chat_completion_chunk(
|
|
408
|
+
{
|
|
409
|
+
"id": "chunk-2",
|
|
410
|
+
"object": "chat.completion.chunk",
|
|
411
|
+
"created": 2,
|
|
412
|
+
"model": "test-model",
|
|
413
|
+
"choices": [
|
|
414
|
+
{
|
|
415
|
+
"index": 0,
|
|
416
|
+
"delta": {"content": '"confidence":0.9}'},
|
|
417
|
+
"finish_reason": "stop",
|
|
418
|
+
"logprobs": None,
|
|
419
|
+
}
|
|
420
|
+
],
|
|
421
|
+
"usage": None,
|
|
422
|
+
}
|
|
423
|
+
),
|
|
424
|
+
]
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
mock_client = mock_async_openai.return_value
|
|
428
|
+
mock_client.chat.completions.create.return_value = streamed_response
|
|
429
|
+
|
|
430
|
+
lm = OpenAIChatCompletionsLanguageModel(minimal_config)
|
|
431
|
+
parsed = await lm.generate_parsed_response(ParsedResponse)
|
|
432
|
+
|
|
433
|
+
assert parsed == ParsedResponse(answer="ok", confidence=0.9)
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
@pytest.mark.asyncio
|
|
437
|
+
async def test_generate_response_streamed_chat_completion_chunks(
|
|
438
|
+
mock_async_openai,
|
|
439
|
+
minimal_config,
|
|
440
|
+
):
|
|
441
|
+
"""Test a streamed chat completion is aggregated into a single response."""
|
|
442
|
+
streamed_response = FakeAsyncStream(
|
|
443
|
+
[
|
|
444
|
+
make_chat_completion_chunk(
|
|
445
|
+
{
|
|
446
|
+
"id": "chunk-1",
|
|
447
|
+
"object": "chat.completion.chunk",
|
|
448
|
+
"created": 1,
|
|
449
|
+
"model": "test-model",
|
|
450
|
+
"choices": [
|
|
451
|
+
{
|
|
452
|
+
"index": 0,
|
|
453
|
+
"delta": {"role": "assistant", "content": "Hello"},
|
|
454
|
+
"finish_reason": None,
|
|
455
|
+
"logprobs": None,
|
|
456
|
+
}
|
|
457
|
+
],
|
|
458
|
+
"usage": None,
|
|
459
|
+
}
|
|
460
|
+
),
|
|
461
|
+
make_chat_completion_chunk(
|
|
462
|
+
{
|
|
463
|
+
"id": "chunk-2",
|
|
464
|
+
"object": "chat.completion.chunk",
|
|
465
|
+
"created": 2,
|
|
466
|
+
"model": "test-model",
|
|
467
|
+
"choices": [
|
|
468
|
+
{
|
|
469
|
+
"index": 0,
|
|
470
|
+
"delta": {"content": ", world!"},
|
|
471
|
+
"finish_reason": "stop",
|
|
472
|
+
"logprobs": None,
|
|
473
|
+
}
|
|
474
|
+
],
|
|
475
|
+
"usage": {
|
|
476
|
+
"prompt_tokens": 10,
|
|
477
|
+
"completion_tokens": 4,
|
|
478
|
+
"total_tokens": 14,
|
|
479
|
+
},
|
|
480
|
+
}
|
|
481
|
+
),
|
|
482
|
+
]
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
mock_client = mock_async_openai.return_value
|
|
486
|
+
mock_client.chat.completions.create.return_value = streamed_response
|
|
487
|
+
|
|
488
|
+
lm = OpenAIChatCompletionsLanguageModel(minimal_config)
|
|
489
|
+
(
|
|
490
|
+
content,
|
|
491
|
+
tool_calls,
|
|
492
|
+
input_tokens,
|
|
493
|
+
output_tokens,
|
|
494
|
+
) = await lm.generate_response_with_token_usage()
|
|
495
|
+
|
|
496
|
+
assert content == "Hello, world!"
|
|
497
|
+
assert tool_calls == []
|
|
498
|
+
assert input_tokens == 10
|
|
499
|
+
assert output_tokens == 4
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
@pytest.mark.asyncio
|
|
503
|
+
async def test_generate_response_streamed_tool_calls_and_discards_reasoning_chunks(
|
|
504
|
+
mock_async_openai,
|
|
505
|
+
minimal_config,
|
|
506
|
+
):
|
|
507
|
+
"""Test streamed tool calls are reconstructed while reasoning chunks are ignored."""
|
|
508
|
+
streamed_response = FakeAsyncStream(
|
|
509
|
+
[
|
|
510
|
+
FakeReasoningChunk(),
|
|
511
|
+
make_chat_completion_chunk(
|
|
512
|
+
{
|
|
513
|
+
"id": "chunk-1",
|
|
514
|
+
"object": "chat.completion.chunk",
|
|
515
|
+
"created": 1,
|
|
516
|
+
"model": "test-model",
|
|
517
|
+
"choices": [
|
|
518
|
+
{
|
|
519
|
+
"index": 0,
|
|
520
|
+
"delta": {
|
|
521
|
+
"tool_calls": [
|
|
522
|
+
{
|
|
523
|
+
"index": 0,
|
|
524
|
+
"id": "call_123",
|
|
525
|
+
"type": "function",
|
|
526
|
+
"function": {
|
|
527
|
+
"name": "get_weather",
|
|
528
|
+
"arguments": '{"location"',
|
|
529
|
+
},
|
|
530
|
+
}
|
|
531
|
+
]
|
|
532
|
+
},
|
|
533
|
+
"finish_reason": None,
|
|
534
|
+
"logprobs": None,
|
|
535
|
+
}
|
|
536
|
+
],
|
|
537
|
+
"usage": None,
|
|
538
|
+
}
|
|
539
|
+
),
|
|
540
|
+
make_chat_completion_chunk(
|
|
541
|
+
{
|
|
542
|
+
"id": "chunk-2",
|
|
543
|
+
"object": "chat.completion.chunk",
|
|
544
|
+
"created": 2,
|
|
545
|
+
"model": "test-model",
|
|
546
|
+
"choices": [
|
|
547
|
+
{
|
|
548
|
+
"index": 0,
|
|
549
|
+
"delta": {
|
|
550
|
+
"tool_calls": [
|
|
551
|
+
{
|
|
552
|
+
"index": 0,
|
|
553
|
+
"function": {"arguments": ': "Boston"}'},
|
|
554
|
+
}
|
|
555
|
+
]
|
|
556
|
+
},
|
|
557
|
+
"finish_reason": "tool_calls",
|
|
558
|
+
"logprobs": None,
|
|
559
|
+
}
|
|
560
|
+
],
|
|
561
|
+
"usage": None,
|
|
562
|
+
}
|
|
563
|
+
),
|
|
564
|
+
]
|
|
565
|
+
)
|
|
566
|
+
|
|
567
|
+
mock_client = mock_async_openai.return_value
|
|
568
|
+
mock_client.chat.completions.create.return_value = streamed_response
|
|
569
|
+
|
|
570
|
+
lm = OpenAIChatCompletionsLanguageModel(minimal_config)
|
|
571
|
+
content, tool_calls = await lm.generate_response()
|
|
572
|
+
|
|
573
|
+
assert content == ""
|
|
574
|
+
assert tool_calls == [
|
|
575
|
+
{
|
|
576
|
+
"call_id": "call_123",
|
|
577
|
+
"function": {
|
|
578
|
+
"name": "get_weather",
|
|
579
|
+
"arguments": {"location": "Boston"},
|
|
580
|
+
},
|
|
581
|
+
}
|
|
582
|
+
]
|
|
216
583
|
|
|
217
584
|
|
|
218
585
|
@pytest.mark.asyncio
|
|
@@ -397,6 +764,35 @@ async def test_generate_response_fail_after_max_retries(
|
|
|
397
764
|
mock_sleep.assert_any_await(2)
|
|
398
765
|
|
|
399
766
|
|
|
767
|
+
@pytest.mark.asyncio
|
|
768
|
+
@patch("asyncio.sleep", new_callable=AsyncMock)
|
|
769
|
+
async def test_generate_response_retry_on_internal_server_error(
|
|
770
|
+
mock_sleep,
|
|
771
|
+
mock_async_openai,
|
|
772
|
+
minimal_config,
|
|
773
|
+
):
|
|
774
|
+
"""Test retry logic on InternalServerError."""
|
|
775
|
+
mock_response = MagicMock()
|
|
776
|
+
mock_response.choices[0].message.content = "Success after retry"
|
|
777
|
+
mock_response.choices[0].message.tool_calls = None
|
|
778
|
+
mock_response.usage = None
|
|
779
|
+
|
|
780
|
+
mock_client = mock_async_openai.return_value
|
|
781
|
+
mock_client.chat.completions.create.side_effect = [
|
|
782
|
+
openai.InternalServerError(
|
|
783
|
+
"internal server error", response=MagicMock(), body=None
|
|
784
|
+
),
|
|
785
|
+
mock_response,
|
|
786
|
+
]
|
|
787
|
+
|
|
788
|
+
lm = OpenAIChatCompletionsLanguageModel(minimal_config)
|
|
789
|
+
content, _ = await lm.generate_response(max_attempts=2)
|
|
790
|
+
|
|
791
|
+
assert content == "Success after retry"
|
|
792
|
+
assert mock_client.chat.completions.create.call_count == 2
|
|
793
|
+
mock_sleep.assert_awaited_once_with(1)
|
|
794
|
+
|
|
795
|
+
|
|
400
796
|
@pytest.mark.asyncio
|
|
401
797
|
@pytest.mark.parametrize(
|
|
402
798
|
"exception",
|
|
@@ -184,6 +184,7 @@ async def test_generate_response_success(mock_async_openai, minimal_config):
|
|
|
184
184
|
{"role": "system", "content": "System prompt"},
|
|
185
185
|
{"role": "user", "content": "User prompt"},
|
|
186
186
|
]
|
|
187
|
+
assert call_args.kwargs["store"] is False
|
|
187
188
|
|
|
188
189
|
|
|
189
190
|
@pytest.mark.asyncio
|
|
@@ -219,6 +220,8 @@ async def test_generate_response_with_tool_calls(mock_async_openai, minimal_conf
|
|
|
219
220
|
},
|
|
220
221
|
},
|
|
221
222
|
]
|
|
223
|
+
call_args = mock_client.responses.create.call_args
|
|
224
|
+
assert call_args.kwargs["store"] is False
|
|
222
225
|
|
|
223
226
|
|
|
224
227
|
@pytest.mark.asyncio
|
|
@@ -353,6 +356,35 @@ async def test_generate_response_fail_after_max_retries(
|
|
|
353
356
|
mock_sleep.assert_any_await(2)
|
|
354
357
|
|
|
355
358
|
|
|
359
|
+
@pytest.mark.asyncio
|
|
360
|
+
@patch("asyncio.sleep", new_callable=AsyncMock)
|
|
361
|
+
async def test_generate_response_retry_on_internal_server_error(
|
|
362
|
+
mock_sleep,
|
|
363
|
+
mock_async_openai,
|
|
364
|
+
minimal_config,
|
|
365
|
+
):
|
|
366
|
+
"""Test retry logic on InternalServerError."""
|
|
367
|
+
mock_response = MagicMock()
|
|
368
|
+
mock_response.output_text = "Success after retry"
|
|
369
|
+
mock_response.output = None
|
|
370
|
+
mock_response.usage = None
|
|
371
|
+
|
|
372
|
+
mock_client = mock_async_openai.return_value
|
|
373
|
+
mock_client.responses.create.side_effect = [
|
|
374
|
+
openai.InternalServerError(
|
|
375
|
+
"internal server error", response=MagicMock(), body=None
|
|
376
|
+
),
|
|
377
|
+
mock_response,
|
|
378
|
+
]
|
|
379
|
+
|
|
380
|
+
lm = OpenAIResponsesLanguageModel(minimal_config)
|
|
381
|
+
content, _ = await lm.generate_response(max_attempts=2)
|
|
382
|
+
|
|
383
|
+
assert content == "Success after retry"
|
|
384
|
+
assert mock_client.responses.create.call_count == 2
|
|
385
|
+
mock_sleep.assert_awaited_once_with(1)
|
|
386
|
+
|
|
387
|
+
|
|
356
388
|
@pytest.mark.asyncio
|
|
357
389
|
@pytest.mark.asyncio
|
|
358
390
|
@pytest.mark.parametrize(
|