iris-vector-rag 0.6.0__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/PKG-INFO +1 -1
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/__init__.py +1 -1
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/hybrid_graphrag.py +145 -5
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag.egg-info/PKG-INFO +1 -1
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag.egg-info/SOURCES.txt +1 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/pyproject.toml +1 -1
- iris_vector_rag-0.7.0/tests/test_attach_corpus.py +362 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/LICENSE +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/README.md +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/adapters/rag_templates_bridge.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/cleanup_job.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/cli.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/main.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/mcp_routes.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/middleware/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/middleware/auth.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/middleware/logging.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/middleware/rate_limit.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/models/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/models/auth.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/models/errors.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/models/health.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/models/pipeline.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/models/quota.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/models/request.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/models/response.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/models/upload.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/models/websocket.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/routes/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/routes/document.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/routes/health.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/routes/pipeline.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/routes/query.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/services/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/services/auth_service.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/services/document_service.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/services/pipeline_manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/websocket/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/websocket/connection.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/websocket/handlers.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/websocket/routes.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/batch_utils.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/config.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/connection_manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/connection_pool.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/database.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/database_schema_manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/db_init_with_indexes.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/db_vector_utils.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/environment_manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/exceptions.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/huggingface_utils.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/iris_client.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/iris_connection.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/iris_connection_manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/iris_connection_pool.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/iris_connector.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/iris_dbapi_connector.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/iris_globals.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/iris_index_utils.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/iris_sql_utils.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/iris_stream_reader.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/llm_cache_config.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/llm_cache_disk.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/llm_cache_iris.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/llm_cache_manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/utils.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/common/vector_sql_utils.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/config/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/config/backend_modes.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/config/config_manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/config/default_config.yaml +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/config/embedding_config.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/config/entities.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/config/manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/config/pipeline_config_service.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/config/validators.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/core/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/core/base.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/core/connection.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/core/exceptions.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/core/models.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/core/response_standardizer.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/core/validators.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/core/vector_store.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/core/vector_store_exceptions.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/dspy_modules/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/dspy_modules/batch_entity_extraction.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/dspy_modules/entity_extraction_module.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/dspy_modules/iris_llm_lm.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/embeddings/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/embeddings/entity_extractor.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/embeddings/iris_embedding.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/embeddings/manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/evaluation/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/evaluation/datasets.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/evaluation/metrics.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/exceptions.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/executor.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/mcp/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/mcp/__main__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/mcp/bridge.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/mcp/cli.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/mcp/config.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/mcp/iris_llm_handler.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/mcp/technique_handlers.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/mcp/tool_schemas.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/mcp/validation.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/memory/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/memory/knowledge_extractor.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/memory/models.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/memory/rag_integration.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/memory/temporal_manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/monitoring/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/ontology/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/ontology/loader.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/ontology/models.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/ontology/plugins/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/ontology/plugins/general_ontology.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/ontology/reasoner.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/optimization/cache_manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/optimization/connection_pool.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/optimization/database_optimizer.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/optimization/hnsw_tuner.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/optimization/parallel_processor.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/optimization/performance_monitor.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/_hybrid_utils.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/basic.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/basic_rerank.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/colbert_iris/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/colbert_iris/ingest.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/colbert_iris/maxsim_indb.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/colbert_iris/pipeline.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/colbert_iris/plaid.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/colbert_iris/schema.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/colbert_iris/vecindex_phase2.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/colbert_pylate/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/colbert_pylate/pylate_pipeline.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/crag.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/factory.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/graphrag.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/graphrag_merged.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/hybrid_graphrag_discovery.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/hybrid_graphrag_retrieval.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/iris_global_graphrag.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/multi_query_rrf.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/plugins/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/plugins/interface.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/security/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/services/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/services/batch_entity_processor.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/services/entity_extraction.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/services/storage.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/storage/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/storage/clob_handler.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/storage/constants.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/storage/enterprise_storage.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/storage/hybrid_schema_manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/storage/iris_embedding_ops.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/storage/metadata_filter_manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/storage/schema_manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/storage/vector_store_iris.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/testing/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/testing/backend_manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/testing/connection_pool.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/testing/exceptions.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/testing/iris_devtools_bridge.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/testing/validators.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/tools/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/tools/graphrag.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/utils/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/utils/module_loader.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/utils/project_root.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/utils/token_counter.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/validation/__init__.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/validation/factory.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/validation/orchestrator.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/validation/requirements.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/validation/validator.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag.egg-info/dependency_links.txt +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag.egg-info/entry_points.txt +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag.egg-info/requires.txt +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag.egg-info/top_level.txt +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/setup.cfg +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_comprehensive_pipeline_validation_e2e.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_comprehensive_pipeline_validation_e2e_fixed.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_enterprise_storage.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_entity_extraction_service.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_fuzzy_search_quick.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_hybrid_graphrag_functional.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_index_ensure.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_ontology_loader.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_ontology_support.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_performance_monitor_comprehensive.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_performance_monitor_working.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_pylate_colbert_pipeline.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_schema_manager_bugs.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_temporal_manager.py +0 -0
- {iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/tests/test_vector_safe_helpers.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iris-vector-rag
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Enterprise RAG pipelines with native IRIS vector search. 6 production implementations with RAGAS evaluation, LangChain, AWS/Azure configs. No external VectorDB required.
|
|
5
5
|
Author-email: Thomas Dyar <thomas.dyar@intersystems.com>
|
|
6
6
|
Maintainer-email: Thomas Dyar <thomas.dyar@intersystems.com>
|
|
@@ -19,7 +19,7 @@ from .validation.requirements import get_pipeline_requirements
|
|
|
19
19
|
from .validation.validator import PreConditionValidator
|
|
20
20
|
|
|
21
21
|
# Package version
|
|
22
|
-
__version__ = "0.
|
|
22
|
+
__version__ = "0.7.0"
|
|
23
23
|
__author__ = "InterSystems IRIS RAG Templates Project"
|
|
24
24
|
__description__ = "A comprehensive, production-ready framework for implementing Retrieval Augmented Generation (RAG) pipelines using InterSystems IRIS as the vector database backend."
|
|
25
25
|
|
{iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/pipelines/hybrid_graphrag.py
RENAMED
|
@@ -10,7 +10,7 @@ robust error handling, and modular architecture.
|
|
|
10
10
|
|
|
11
11
|
import logging
|
|
12
12
|
import time
|
|
13
|
-
from typing import Any, Callable, Dict, List, Optional
|
|
13
|
+
from typing import Any, Callable, Dict, List, Optional, TypedDict
|
|
14
14
|
|
|
15
15
|
from ..config.manager import ConfigurationManager
|
|
16
16
|
from ..core.connection import ConnectionManager
|
|
@@ -22,6 +22,20 @@ from .hybrid_graphrag_retrieval import HybridRetrievalMethods
|
|
|
22
22
|
logger = logging.getLogger(__name__)
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
class AttachResult(TypedDict):
|
|
26
|
+
table: str
|
|
27
|
+
label: str
|
|
28
|
+
id_col: str
|
|
29
|
+
embedding_col: str
|
|
30
|
+
dimension: int
|
|
31
|
+
row_count: int
|
|
32
|
+
has_hnsw_index: Optional[bool]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class DimensionMismatchError(ValueError):
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
|
|
25
39
|
class HybridGraphRAGPipeline(GraphRAGPipeline):
|
|
26
40
|
"""
|
|
27
41
|
Enhanced GraphRAG pipeline with hybrid search capabilities.
|
|
@@ -48,7 +62,13 @@ class HybridGraphRAGPipeline(GraphRAGPipeline):
|
|
|
48
62
|
embedding_config: Optional[str] = None,
|
|
49
63
|
executor=None,
|
|
50
64
|
):
|
|
51
|
-
super().__init__(
|
|
65
|
+
super().__init__(
|
|
66
|
+
connection_manager,
|
|
67
|
+
config_manager,
|
|
68
|
+
llm_func,
|
|
69
|
+
vector_store,
|
|
70
|
+
executor=executor,
|
|
71
|
+
)
|
|
52
72
|
|
|
53
73
|
# Store schema manager for iris_vector_graph table management
|
|
54
74
|
self.schema_manager = schema_manager
|
|
@@ -73,6 +93,8 @@ class HybridGraphRAGPipeline(GraphRAGPipeline):
|
|
|
73
93
|
self.text_engine = None
|
|
74
94
|
self.vector_optimizer = None
|
|
75
95
|
|
|
96
|
+
self._attached_corpora: Dict[str, AttachResult] = {}
|
|
97
|
+
|
|
76
98
|
# Initialize graph core integration
|
|
77
99
|
self._initialize_graph_core()
|
|
78
100
|
|
|
@@ -147,6 +169,116 @@ class HybridGraphRAGPipeline(GraphRAGPipeline):
|
|
|
147
169
|
logger.error(f"Failed to initialize iris_vector_graph components: {e}")
|
|
148
170
|
raise
|
|
149
171
|
|
|
172
|
+
def _detect_hnsw_index(
|
|
173
|
+
self, source_table: str, embedding_col: str
|
|
174
|
+
) -> Optional[bool]:
|
|
175
|
+
try:
|
|
176
|
+
schema, tbl = (
|
|
177
|
+
source_table.split(".", 1)
|
|
178
|
+
if "." in source_table
|
|
179
|
+
else ("", source_table)
|
|
180
|
+
)
|
|
181
|
+
conn = self.iris_engine.conn if self.iris_engine else None
|
|
182
|
+
if conn is None:
|
|
183
|
+
return None
|
|
184
|
+
cur = conn.cursor()
|
|
185
|
+
try:
|
|
186
|
+
cur.execute(
|
|
187
|
+
"SELECT COUNT(*) FROM INFORMATION_SCHEMA.INDEXES "
|
|
188
|
+
"WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND COLUMN_NAME = ?",
|
|
189
|
+
[schema or "USER", tbl, embedding_col],
|
|
190
|
+
)
|
|
191
|
+
row = cur.fetchone()
|
|
192
|
+
return row is not None and int(row[0]) > 0
|
|
193
|
+
finally:
|
|
194
|
+
cur.close()
|
|
195
|
+
except Exception:
|
|
196
|
+
return None
|
|
197
|
+
|
|
198
|
+
def attach_existing_corpus(
|
|
199
|
+
self,
|
|
200
|
+
source_table: str,
|
|
201
|
+
id_col: str,
|
|
202
|
+
text_col: str,
|
|
203
|
+
embedding_col: str,
|
|
204
|
+
graph_label: str,
|
|
205
|
+
) -> AttachResult:
|
|
206
|
+
if self.iris_engine is None:
|
|
207
|
+
raise RuntimeError(
|
|
208
|
+
"iris_vector_graph engine not initialized. "
|
|
209
|
+
"Call _initialize_graph_core() first."
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
validation = self.iris_engine.validate_vector_table(source_table, embedding_col)
|
|
213
|
+
dimension = validation.get("dimension")
|
|
214
|
+
row_count = validation.get("row_count", 0)
|
|
215
|
+
|
|
216
|
+
if dimension is None and row_count > 0:
|
|
217
|
+
cur = self.iris_engine.conn.cursor()
|
|
218
|
+
try:
|
|
219
|
+
cur.execute(
|
|
220
|
+
f"SELECT TOP 1 {embedding_col} "
|
|
221
|
+
f"FROM {source_table} WHERE {embedding_col} IS NOT NULL"
|
|
222
|
+
)
|
|
223
|
+
row = cur.fetchone()
|
|
224
|
+
if row and row[0]:
|
|
225
|
+
raw = row[0]
|
|
226
|
+
if isinstance(raw, str):
|
|
227
|
+
dimension = raw.count(",") + 1
|
|
228
|
+
elif isinstance(raw, (list, tuple)):
|
|
229
|
+
dimension = len(raw)
|
|
230
|
+
elif isinstance(raw, bytes):
|
|
231
|
+
dimension = len(raw) // 8
|
|
232
|
+
except Exception:
|
|
233
|
+
pass
|
|
234
|
+
finally:
|
|
235
|
+
cur.close()
|
|
236
|
+
|
|
237
|
+
if dimension is None or dimension == 0:
|
|
238
|
+
logger.warning(
|
|
239
|
+
f"No non-NULL embeddings found in {source_table}.{embedding_col} — "
|
|
240
|
+
f"vector search will return no results until embeddings are populated."
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
self.iris_engine.map_sql_table(
|
|
244
|
+
source_table,
|
|
245
|
+
id_col,
|
|
246
|
+
graph_label,
|
|
247
|
+
property_columns=[text_col],
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
has_hnsw = self._detect_hnsw_index(source_table, embedding_col)
|
|
251
|
+
if has_hnsw is False:
|
|
252
|
+
logger.warning(
|
|
253
|
+
f"No HNSW index found on {source_table}.{embedding_col} — "
|
|
254
|
+
f"vector search will use brute force. "
|
|
255
|
+
f"Consider running BUILD INDEX for better performance."
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
result: AttachResult = {
|
|
259
|
+
"table": source_table,
|
|
260
|
+
"label": graph_label,
|
|
261
|
+
"id_col": id_col,
|
|
262
|
+
"embedding_col": embedding_col,
|
|
263
|
+
"dimension": dimension if dimension else 0,
|
|
264
|
+
"row_count": row_count,
|
|
265
|
+
"has_hnsw_index": has_hnsw,
|
|
266
|
+
}
|
|
267
|
+
self._attached_corpora[graph_label] = result
|
|
268
|
+
return result
|
|
269
|
+
|
|
270
|
+
def _validate_query_dimension(self, graph_label: str, query_vec) -> None:
|
|
271
|
+
if graph_label not in self._attached_corpora:
|
|
272
|
+
return
|
|
273
|
+
expected_dim = self._attached_corpora[graph_label].get("dimension", 0)
|
|
274
|
+
if expected_dim and expected_dim > 0:
|
|
275
|
+
actual_dim = len(query_vec) if hasattr(query_vec, "__len__") else 0
|
|
276
|
+
if actual_dim > 0 and actual_dim != expected_dim:
|
|
277
|
+
raise DimensionMismatchError(
|
|
278
|
+
f"Query vector dimension ({actual_dim}) does not match "
|
|
279
|
+
f"table embedding dimension ({expected_dim})"
|
|
280
|
+
)
|
|
281
|
+
|
|
150
282
|
def query(
|
|
151
283
|
self,
|
|
152
284
|
query_text: Optional[str] = None,
|
|
@@ -282,7 +414,11 @@ class HybridGraphRAGPipeline(GraphRAGPipeline):
|
|
|
282
414
|
normalized: List[Document] = []
|
|
283
415
|
for doc in documents:
|
|
284
416
|
if isinstance(doc, Document):
|
|
285
|
-
score =
|
|
417
|
+
score = (
|
|
418
|
+
doc.metadata.get("similarity_score")
|
|
419
|
+
if hasattr(doc, "metadata")
|
|
420
|
+
else None
|
|
421
|
+
)
|
|
286
422
|
score_value = float(score) if score is not None else 1.0
|
|
287
423
|
normalized.append(
|
|
288
424
|
Document(
|
|
@@ -354,7 +490,9 @@ class HybridGraphRAGPipeline(GraphRAGPipeline):
|
|
|
354
490
|
)
|
|
355
491
|
# If text search returns 0 results, fall back to vector search
|
|
356
492
|
if not documents:
|
|
357
|
-
logger.warning(
|
|
493
|
+
logger.warning(
|
|
494
|
+
"Text search returned 0 results. Falling back to vector search."
|
|
495
|
+
)
|
|
358
496
|
fallback_docs = self._fallback_to_vector_search(query_text, top_k)
|
|
359
497
|
return fallback_docs, "vector_fallback"
|
|
360
498
|
return documents, method
|
|
@@ -374,7 +512,9 @@ class HybridGraphRAGPipeline(GraphRAGPipeline):
|
|
|
374
512
|
)
|
|
375
513
|
# If HNSW returns 0 results, fall back to IRISVectorStore
|
|
376
514
|
if not documents:
|
|
377
|
-
logger.warning(
|
|
515
|
+
logger.warning(
|
|
516
|
+
"HNSW vector search returned 0 results. Falling back to IRISVectorStore."
|
|
517
|
+
)
|
|
378
518
|
fallback_docs = self._fallback_to_vector_search(query_text, top_k)
|
|
379
519
|
return fallback_docs, "vector_fallback"
|
|
380
520
|
return documents, method
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iris-vector-rag
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Enterprise RAG pipelines with native IRIS vector search. 6 production implementations with RAGAS evaluation, LangChain, AWS/Azure configs. No external VectorDB required.
|
|
5
5
|
Author-email: Thomas Dyar <thomas.dyar@intersystems.com>
|
|
6
6
|
Maintainer-email: Thomas Dyar <thomas.dyar@intersystems.com>
|
|
@@ -182,6 +182,7 @@ iris_vector_rag/validation/factory.py
|
|
|
182
182
|
iris_vector_rag/validation/orchestrator.py
|
|
183
183
|
iris_vector_rag/validation/requirements.py
|
|
184
184
|
iris_vector_rag/validation/validator.py
|
|
185
|
+
tests/test_attach_corpus.py
|
|
185
186
|
tests/test_comprehensive_pipeline_validation_e2e.py
|
|
186
187
|
tests/test_comprehensive_pipeline_validation_e2e_fixed.py
|
|
187
188
|
tests/test_enterprise_storage.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "iris-vector-rag"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.7.0"
|
|
8
8
|
description = "Enterprise RAG pipelines with native IRIS vector search. 6 production implementations with RAGAS evaluation, LangChain, AWS/Azure configs. No external VectorDB required."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
IRIS_HOST = os.environ.get("IRIS_HOSTNAME", "localhost")
|
|
8
|
+
IRIS_PORT = int(os.environ.get("IRIS_PORT", "1972"))
|
|
9
|
+
TOKEN_DIM = 384
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _get_conn():
|
|
15
|
+
import iris.dbapi as dbapi
|
|
16
|
+
|
|
17
|
+
return dbapi.connect(
|
|
18
|
+
hostname=IRIS_HOST,
|
|
19
|
+
port=IRIS_PORT,
|
|
20
|
+
namespace="USER",
|
|
21
|
+
username="_SYSTEM",
|
|
22
|
+
password="SYS",
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _get_engine(conn):
|
|
27
|
+
import intersystems_iris
|
|
28
|
+
from iris_vector_graph import IRISGraphEngine
|
|
29
|
+
|
|
30
|
+
native = intersystems_iris.createConnection(
|
|
31
|
+
hostname=IRIS_HOST,
|
|
32
|
+
port=IRIS_PORT,
|
|
33
|
+
namespace="USER",
|
|
34
|
+
username="_SYSTEM",
|
|
35
|
+
password="SYS",
|
|
36
|
+
)
|
|
37
|
+
return IRISGraphEngine(native)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _create_test_table(conn, table_name, n_rows, dim=TOKEN_DIM):
|
|
41
|
+
cur = conn.cursor()
|
|
42
|
+
try:
|
|
43
|
+
cur.execute(f"DROP TABLE IF EXISTS {table_name}")
|
|
44
|
+
conn.commit()
|
|
45
|
+
cur.execute(
|
|
46
|
+
f"CREATE TABLE {table_name} ("
|
|
47
|
+
f"doc_id VARCHAR(50) PRIMARY KEY, "
|
|
48
|
+
f"text_content VARCHAR(2000), "
|
|
49
|
+
f"embedding VECTOR(DOUBLE, {dim}))"
|
|
50
|
+
)
|
|
51
|
+
conn.commit()
|
|
52
|
+
rng = np.random.default_rng(42)
|
|
53
|
+
for i in range(n_rows):
|
|
54
|
+
vec = rng.random(dim).astype(np.float32)
|
|
55
|
+
vec /= np.linalg.norm(vec)
|
|
56
|
+
vec_str = ",".join(str(float(v)) for v in vec)
|
|
57
|
+
cur.execute(
|
|
58
|
+
f"INSERT INTO {table_name} (doc_id, text_content, embedding) "
|
|
59
|
+
f"VALUES (?, ?, TO_VECTOR(?, DOUBLE, {dim}))",
|
|
60
|
+
[f"doc_{i:04d}", f"Test document {i} about topic {i % 10}.", vec_str],
|
|
61
|
+
)
|
|
62
|
+
conn.commit()
|
|
63
|
+
finally:
|
|
64
|
+
cur.close()
|
|
65
|
+
return n_rows
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _drop_test_table(conn, table_name):
|
|
69
|
+
cur = conn.cursor()
|
|
70
|
+
try:
|
|
71
|
+
cur.execute(f"DROP TABLE IF EXISTS {table_name}")
|
|
72
|
+
conn.commit()
|
|
73
|
+
except Exception:
|
|
74
|
+
pass
|
|
75
|
+
finally:
|
|
76
|
+
cur.close()
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _make_pipeline(conn, engine):
|
|
80
|
+
from unittest.mock import MagicMock
|
|
81
|
+
|
|
82
|
+
from iris_vector_rag.pipelines.hybrid_graphrag import HybridGraphRAGPipeline
|
|
83
|
+
|
|
84
|
+
pipeline = HybridGraphRAGPipeline.__new__(HybridGraphRAGPipeline)
|
|
85
|
+
pipeline.iris_engine = engine
|
|
86
|
+
pipeline._attached_corpora = {}
|
|
87
|
+
pipeline.connection_manager = MagicMock()
|
|
88
|
+
pipeline.config_manager = MagicMock()
|
|
89
|
+
return pipeline
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@pytest.fixture(scope="module")
|
|
93
|
+
def conn():
|
|
94
|
+
c = _get_conn()
|
|
95
|
+
yield c
|
|
96
|
+
c.close()
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@pytest.fixture(scope="module")
|
|
100
|
+
def engine(conn):
|
|
101
|
+
import intersystems_iris
|
|
102
|
+
|
|
103
|
+
native = intersystems_iris.createConnection(
|
|
104
|
+
hostname=IRIS_HOST,
|
|
105
|
+
port=IRIS_PORT,
|
|
106
|
+
namespace="USER",
|
|
107
|
+
username="_SYSTEM",
|
|
108
|
+
password="SYS",
|
|
109
|
+
)
|
|
110
|
+
from iris_vector_graph import IRISGraphEngine
|
|
111
|
+
|
|
112
|
+
e = IRISGraphEngine(native, embedding_dimension=TOKEN_DIM)
|
|
113
|
+
e.initialize_schema(auto_deploy_objectscript=False)
|
|
114
|
+
return e
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@pytest.fixture(scope="module")
|
|
118
|
+
def pipeline(conn, engine):
|
|
119
|
+
return _make_pipeline(conn, engine)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@pytest.fixture(scope="module")
|
|
123
|
+
def test_table(conn):
|
|
124
|
+
table = "Test069.CorpusA"
|
|
125
|
+
_create_test_table(conn, table, 100)
|
|
126
|
+
yield table
|
|
127
|
+
_drop_test_table(conn, table)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
# --- US1: Attach RAG corpus ---
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@pytest.mark.integration
|
|
134
|
+
class TestAttachCorpusBasic:
|
|
135
|
+
def test_attach_returns_result(self, pipeline, test_table):
|
|
136
|
+
result = pipeline.attach_existing_corpus(
|
|
137
|
+
source_table=test_table,
|
|
138
|
+
id_col="doc_id",
|
|
139
|
+
text_col="text_content",
|
|
140
|
+
embedding_col="embedding",
|
|
141
|
+
graph_label="TestDoc",
|
|
142
|
+
)
|
|
143
|
+
assert result["table"] == test_table
|
|
144
|
+
assert result["label"] == "TestDoc"
|
|
145
|
+
assert result["dimension"] == TOKEN_DIM
|
|
146
|
+
assert result["row_count"] == 100
|
|
147
|
+
assert isinstance(result["has_hnsw_index"], (bool, type(None)))
|
|
148
|
+
|
|
149
|
+
def test_graph_query_returns_rows(self, pipeline, engine, test_table):
|
|
150
|
+
pipeline.attach_existing_corpus(
|
|
151
|
+
source_table=test_table,
|
|
152
|
+
id_col="doc_id",
|
|
153
|
+
text_col="text_content",
|
|
154
|
+
embedding_col="embedding",
|
|
155
|
+
graph_label="TestDoc2",
|
|
156
|
+
)
|
|
157
|
+
results = engine.execute_cypher("MATCH (d:TestDoc2) RETURN d.doc_id LIMIT 5")
|
|
158
|
+
assert len(results) > 0
|
|
159
|
+
|
|
160
|
+
def test_vector_search_returns_results(self, pipeline, engine, test_table):
|
|
161
|
+
pipeline.attach_existing_corpus(
|
|
162
|
+
source_table=test_table,
|
|
163
|
+
id_col="doc_id",
|
|
164
|
+
text_col="text_content",
|
|
165
|
+
embedding_col="embedding",
|
|
166
|
+
graph_label="TestDocVS",
|
|
167
|
+
)
|
|
168
|
+
rng = np.random.default_rng(99)
|
|
169
|
+
q = rng.random(TOKEN_DIM).astype(np.float32)
|
|
170
|
+
q /= np.linalg.norm(q)
|
|
171
|
+
results = engine.vector_search(
|
|
172
|
+
test_table, "embedding", q.tolist(), top_k=5, id_col="doc_id"
|
|
173
|
+
)
|
|
174
|
+
assert len(results) > 0
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@pytest.mark.integration
|
|
178
|
+
class TestAttachCorpusIdempotent:
|
|
179
|
+
def test_double_attach_no_error(self, pipeline, test_table):
|
|
180
|
+
r1 = pipeline.attach_existing_corpus(
|
|
181
|
+
source_table=test_table,
|
|
182
|
+
id_col="doc_id",
|
|
183
|
+
text_col="text_content",
|
|
184
|
+
embedding_col="embedding",
|
|
185
|
+
graph_label="IdempotentLabel",
|
|
186
|
+
)
|
|
187
|
+
r2 = pipeline.attach_existing_corpus(
|
|
188
|
+
source_table=test_table,
|
|
189
|
+
id_col="doc_id",
|
|
190
|
+
text_col="text_content",
|
|
191
|
+
embedding_col="embedding",
|
|
192
|
+
graph_label="IdempotentLabel",
|
|
193
|
+
)
|
|
194
|
+
assert r1["dimension"] == r2["dimension"]
|
|
195
|
+
assert r1["label"] == r2["label"]
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@pytest.mark.integration
|
|
199
|
+
class TestNewRowsVisible:
|
|
200
|
+
def test_new_row_in_graph_after_insert(self, pipeline, conn, engine, test_table):
|
|
201
|
+
pipeline.attach_existing_corpus(
|
|
202
|
+
source_table=test_table,
|
|
203
|
+
id_col="doc_id",
|
|
204
|
+
text_col="text_content",
|
|
205
|
+
embedding_col="embedding",
|
|
206
|
+
graph_label="NewRowLabel",
|
|
207
|
+
)
|
|
208
|
+
cur = conn.cursor()
|
|
209
|
+
rng = np.random.default_rng(777)
|
|
210
|
+
vec = rng.random(TOKEN_DIM).astype(np.float32)
|
|
211
|
+
vec /= np.linalg.norm(vec)
|
|
212
|
+
vec_str = ",".join(str(float(v)) for v in vec)
|
|
213
|
+
try:
|
|
214
|
+
cur.execute(
|
|
215
|
+
f"INSERT INTO {test_table} (doc_id, text_content, embedding) "
|
|
216
|
+
f"VALUES (?, ?, TO_VECTOR(?, FLOAT, {TOKEN_DIM}))",
|
|
217
|
+
["doc_new_0001", "Newly inserted document.", vec_str],
|
|
218
|
+
)
|
|
219
|
+
conn.commit()
|
|
220
|
+
finally:
|
|
221
|
+
cur.close()
|
|
222
|
+
results = engine.execute_cypher(
|
|
223
|
+
"MATCH (d:NewRowLabel) WHERE d.doc_id = 'doc_new_0001' RETURN d.doc_id"
|
|
224
|
+
)
|
|
225
|
+
assert len(results) > 0
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
# --- US2: Custom IRIS table ---
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
@pytest.mark.integration
|
|
232
|
+
class TestAttachCustomTable:
|
|
233
|
+
def test_custom_schema_table(self, conn, engine):
|
|
234
|
+
p = _make_pipeline(conn, engine)
|
|
235
|
+
table = "Test069.ClinicalNotes"
|
|
236
|
+
_create_test_table(conn, table, 50, dim=384)
|
|
237
|
+
try:
|
|
238
|
+
result = p.attach_existing_corpus(
|
|
239
|
+
source_table=table,
|
|
240
|
+
id_col="doc_id",
|
|
241
|
+
text_col="text_content",
|
|
242
|
+
embedding_col="embedding",
|
|
243
|
+
graph_label="ClinNote",
|
|
244
|
+
)
|
|
245
|
+
assert result["label"] == "ClinNote"
|
|
246
|
+
assert result["row_count"] == 50
|
|
247
|
+
results = engine.execute_cypher(
|
|
248
|
+
"MATCH (n:ClinNote) RETURN n.doc_id LIMIT 3"
|
|
249
|
+
)
|
|
250
|
+
assert len(results) > 0
|
|
251
|
+
finally:
|
|
252
|
+
_drop_test_table(conn, table)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
# --- US3: Dimension mismatch ---
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
@pytest.mark.integration
|
|
259
|
+
class TestDimensionMismatch:
|
|
260
|
+
def test_mismatch_raises_error(self, pipeline, test_table):
|
|
261
|
+
from iris_vector_rag.pipelines.hybrid_graphrag import DimensionMismatchError
|
|
262
|
+
|
|
263
|
+
pipeline.attach_existing_corpus(
|
|
264
|
+
source_table=test_table,
|
|
265
|
+
id_col="doc_id",
|
|
266
|
+
text_col="text_content",
|
|
267
|
+
embedding_col="embedding",
|
|
268
|
+
graph_label="DimTest",
|
|
269
|
+
)
|
|
270
|
+
wrong_dim_vec = np.random.default_rng(0).random(768).tolist()
|
|
271
|
+
with pytest.raises(DimensionMismatchError):
|
|
272
|
+
pipeline._validate_query_dimension("DimTest", wrong_dim_vec)
|
|
273
|
+
|
|
274
|
+
def test_all_null_embeddings_warns(self, conn, engine, caplog):
|
|
275
|
+
p = _make_pipeline(conn, engine)
|
|
276
|
+
table = "Test069.NullEmb"
|
|
277
|
+
cur = conn.cursor()
|
|
278
|
+
try:
|
|
279
|
+
cur.execute(f"DROP TABLE IF EXISTS {table}")
|
|
280
|
+
conn.commit()
|
|
281
|
+
cur.execute(
|
|
282
|
+
f"CREATE TABLE {table} ("
|
|
283
|
+
f"doc_id VARCHAR(50) PRIMARY KEY, "
|
|
284
|
+
f"text_content VARCHAR(200), "
|
|
285
|
+
f"embedding VECTOR(DOUBLE, 384))"
|
|
286
|
+
)
|
|
287
|
+
conn.commit()
|
|
288
|
+
cur.execute(
|
|
289
|
+
f"INSERT INTO {table} (doc_id, text_content) VALUES ('n1', 'No embedding')"
|
|
290
|
+
)
|
|
291
|
+
conn.commit()
|
|
292
|
+
finally:
|
|
293
|
+
cur.close()
|
|
294
|
+
try:
|
|
295
|
+
with caplog.at_level(logging.WARNING):
|
|
296
|
+
result = p.attach_existing_corpus(
|
|
297
|
+
source_table=table,
|
|
298
|
+
id_col="doc_id",
|
|
299
|
+
text_col="text_content",
|
|
300
|
+
embedding_col="embedding",
|
|
301
|
+
graph_label="NullLabel",
|
|
302
|
+
)
|
|
303
|
+
assert result["dimension"] is None or result["dimension"] == 0
|
|
304
|
+
assert any(
|
|
305
|
+
"non-NULL" in r.message or "NULL" in r.message for r in caplog.records
|
|
306
|
+
)
|
|
307
|
+
finally:
|
|
308
|
+
_drop_test_table(conn, table)
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
# --- Polish: Edge cases ---
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
@pytest.mark.integration
|
|
315
|
+
class TestEdgeCases:
|
|
316
|
+
def test_nonexistent_table_raises(self, pipeline):
|
|
317
|
+
with pytest.raises(ValueError, match="not found"):
|
|
318
|
+
pipeline.attach_existing_corpus(
|
|
319
|
+
source_table="NoSuch.Table",
|
|
320
|
+
id_col="id",
|
|
321
|
+
text_col="txt",
|
|
322
|
+
embedding_col="emb",
|
|
323
|
+
graph_label="Ghost",
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
def test_nonexistent_column_raises(self, pipeline, test_table):
|
|
327
|
+
with pytest.raises(ValueError, match="not found"):
|
|
328
|
+
pipeline.attach_existing_corpus(
|
|
329
|
+
source_table=test_table,
|
|
330
|
+
id_col="doc_id",
|
|
331
|
+
text_col="text_content",
|
|
332
|
+
embedding_col="no_such_column",
|
|
333
|
+
graph_label="BadCol",
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
def test_upsert_repoint_label(self, conn, engine):
|
|
337
|
+
p = _make_pipeline(conn, engine)
|
|
338
|
+
table_a = "Test069.TableA"
|
|
339
|
+
table_b = "Test069.TableB"
|
|
340
|
+
_create_test_table(conn, table_a, 10)
|
|
341
|
+
_create_test_table(conn, table_b, 20)
|
|
342
|
+
try:
|
|
343
|
+
r1 = p.attach_existing_corpus(
|
|
344
|
+
source_table=table_a,
|
|
345
|
+
id_col="doc_id",
|
|
346
|
+
text_col="text_content",
|
|
347
|
+
embedding_col="embedding",
|
|
348
|
+
graph_label="Repoint",
|
|
349
|
+
)
|
|
350
|
+
assert r1["row_count"] == 10
|
|
351
|
+
r2 = p.attach_existing_corpus(
|
|
352
|
+
source_table=table_b,
|
|
353
|
+
id_col="doc_id",
|
|
354
|
+
text_col="text_content",
|
|
355
|
+
embedding_col="embedding",
|
|
356
|
+
graph_label="Repoint",
|
|
357
|
+
)
|
|
358
|
+
assert r2["row_count"] == 20
|
|
359
|
+
assert r2["table"] == table_b
|
|
360
|
+
finally:
|
|
361
|
+
_drop_test_table(conn, table_a)
|
|
362
|
+
_drop_test_table(conn, table_b)
|
|
File without changes
|
|
File without changes
|
{iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/adapters/rag_templates_bridge.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iris_vector_rag-0.6.0 → iris_vector_rag-0.7.0}/iris_vector_rag/api/middleware/rate_limit.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|