contextsynapse 1.0.0__py3-none-any.whl
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.
- contextsynapse/__init__.py +107 -0
- contextsynapse/__main__.py +9 -0
- contextsynapse/a2a/__init__.py +28 -0
- contextsynapse/a2a/client.py +120 -0
- contextsynapse/a2a/discovery.py +128 -0
- contextsynapse/a2a/handlers.py +164 -0
- contextsynapse/a2a/models.py +246 -0
- contextsynapse/a2a/streaming.py +92 -0
- contextsynapse/a2a/task_manager.py +275 -0
- contextsynapse/adapters/__init__.py +98 -0
- contextsynapse/adapters/_base.py +298 -0
- contextsynapse/adapters/autogen/__init__.py +4 -0
- contextsynapse/adapters/autogen/tools.py +34 -0
- contextsynapse/adapters/crewai/__init__.py +4 -0
- contextsynapse/adapters/crewai/tools.py +63 -0
- contextsynapse/adapters/langchain/__init__.py +19 -0
- contextsynapse/adapters/langchain/message_history.py +17 -0
- contextsynapse/adapters/langchain/retriever.py +158 -0
- contextsynapse/adapters/langchain/tools.py +43 -0
- contextsynapse/adapters/langgraph/__init__.py +21 -0
- contextsynapse/adapters/langgraph/checkpoint.py +223 -0
- contextsynapse/adapters/langgraph/context_tools.py +341 -0
- contextsynapse/adapters/langgraph/message_history.py +138 -0
- contextsynapse/adapters/langgraph/tools.py +43 -0
- contextsynapse/adapters/llamaindex/__init__.py +4 -0
- contextsynapse/adapters/llamaindex/tools.py +64 -0
- contextsynapse/adapters/openai/__init__.py +24 -0
- contextsynapse/adapters/openai/tools.py +206 -0
- contextsynapse/adapters/pydantic_ai/__init__.py +4 -0
- contextsynapse/adapters/pydantic_ai/tools.py +36 -0
- contextsynapse/adapters/swarm/__init__.py +4 -0
- contextsynapse/adapters/swarm/tools.py +44 -0
- contextsynapse/agents/__init__.py +6 -0
- contextsynapse/agents/auto_capture.py +80 -0
- contextsynapse/agents/dispatcher.py +299 -0
- contextsynapse/agents/notifications.py +112 -0
- contextsynapse/aiql/__init__.py +71 -0
- contextsynapse/aiql/cache.py +341 -0
- contextsynapse/aiql/compiler/__init__.py +62 -0
- contextsynapse/aiql/compiler/optimizer.py +126 -0
- contextsynapse/aiql/compiler/planner.py +366 -0
- contextsynapse/aiql/compiler/statistics.py +235 -0
- contextsynapse/aiql/compiler/validator.py +425 -0
- contextsynapse/aiql/engine/__init__.py +11 -0
- contextsynapse/aiql/engine/chunk_storage.py +2584 -0
- contextsynapse/aiql/engine/executor.py +7737 -0
- contextsynapse/aiql/engine/extraction_integration.py +442 -0
- contextsynapse/aiql/engine/graph_builder.py +405 -0
- contextsynapse/aiql/engine/node_creation_from_normalized.py +691 -0
- contextsynapse/aiql/engine/performance_monitor.py +289 -0
- contextsynapse/aiql/engine/postprocessing.py +365 -0
- contextsynapse/aiql/engine/ray_stage_executors.py +918 -0
- contextsynapse/aiql/engine/redis_cache.py +106 -0
- contextsynapse/aiql/engine/streaming_json.py +366 -0
- contextsynapse/aiql/engine/streaming_parquet.py +568 -0
- contextsynapse/aiql/engine/streaming_ray_chunking.py +419 -0
- contextsynapse/aiql/grammar/__init__.py +14 -0
- contextsynapse/aiql/grammar/aiql_grammar.py +1822 -0
- contextsynapse/aiql/grammar/base.py +71 -0
- contextsynapse/aiql/parser/__init__.py +46 -0
- contextsynapse/aiql/parser/aiql_parser.py +11330 -0
- contextsynapse/aiql/parser/base_parser.py +47 -0
- contextsynapse/api/__init__.py +5 -0
- contextsynapse/api/a2a_router.py +233 -0
- contextsynapse/api/admin_router.py +140 -0
- contextsynapse/api/agent_worker_router.py +978 -0
- contextsynapse/api/algorithms_router.py +317 -0
- contextsynapse/api/api.py +4144 -0
- contextsynapse/api/audit.py +204 -0
- contextsynapse/api/auth.py +441 -0
- contextsynapse/api/auth_router.py +537 -0
- contextsynapse/api/billing.py +261 -0
- contextsynapse/api/billing_router.py +275 -0
- contextsynapse/api/boundary_router.py +452 -0
- contextsynapse/api/cognition_router.py +116 -0
- contextsynapse/api/connector_router.py +237 -0
- contextsynapse/api/context_router.py +1619 -0
- contextsynapse/api/dashboard_router.py +11367 -0
- contextsynapse/api/errors.py +183 -0
- contextsynapse/api/events.py +88 -0
- contextsynapse/api/experiment_bootstrap.py +321 -0
- contextsynapse/api/experiment_orchestrator.py +1078 -0
- contextsynapse/api/experiment_router.py +2089 -0
- contextsynapse/api/feature_gate.py +89 -0
- contextsynapse/api/federation_router.py +108 -0
- contextsynapse/api/integrations.py +567 -0
- contextsynapse/api/integrations_router.py +461 -0
- contextsynapse/api/intelligence_router.py +1028 -0
- contextsynapse/api/metering.py +155 -0
- contextsynapse/api/metrics.py +112 -0
- contextsynapse/api/models.py +38 -0
- contextsynapse/api/monitoring_router.py +174 -0
- contextsynapse/api/pipeline_router.py +1437 -0
- contextsynapse/api/playground_conn.py +116 -0
- contextsynapse/api/projects_router.py +131 -0
- contextsynapse/api/queries_router.py +282 -0
- contextsynapse/api/quota.py +95 -0
- contextsynapse/api/rate_limit.py +64 -0
- contextsynapse/api/search_router.py +261 -0
- contextsynapse/api/shield_router.py +447 -0
- contextsynapse/api/tenant_guard.py +103 -0
- contextsynapse/api/tenant_quotas.py +231 -0
- contextsynapse/api/tenants.py +305 -0
- contextsynapse/api/users.py +646 -0
- contextsynapse/api/v1.py +167 -0
- contextsynapse/api/vertical_builder_router.py +387 -0
- contextsynapse/benchmark/__init__.py +15 -0
- contextsynapse/benchmark/__main__.py +64 -0
- contextsynapse/benchmark/agents.py +338 -0
- contextsynapse/benchmark/live_ab.py +338 -0
- contextsynapse/benchmark/reporter.py +149 -0
- contextsynapse/benchmark/runner.py +264 -0
- contextsynapse/benchmark/savings.py +266 -0
- contextsynapse/benchmark/token_counter.py +212 -0
- contextsynapse/benchmark/workloads.py +289 -0
- contextsynapse/buffer/__init__.py +154 -0
- contextsynapse/buffer/base.py +257 -0
- contextsynapse/buffer/duckdb_buffer.py +246 -0
- contextsynapse/buffer/file_buffer.py +229 -0
- contextsynapse/buffer/lmdb_buffer.py +286 -0
- contextsynapse/buffer/local_buffer.py +154 -0
- contextsynapse/buffer/redis_buffer.py +211 -0
- contextsynapse/buffer/sqlite_buffer.py +266 -0
- contextsynapse/cache.py +2 -0
- contextsynapse/cli/__init__.py +40 -0
- contextsynapse/cli/cli.py +475 -0
- contextsynapse/cli/config_cli.py +177 -0
- contextsynapse/cli/scaffold.py +465 -0
- contextsynapse/cognition/__init__.py +31 -0
- contextsynapse/cognition/derivation.py +55 -0
- contextsynapse/cognition/events.py +135 -0
- contextsynapse/cognition/feedback.py +52 -0
- contextsynapse/cognition/hallucination.py +90 -0
- contextsynapse/cognition/invalidation.py +70 -0
- contextsynapse/cognition/read_tracker.py +50 -0
- contextsynapse/collaboration.py +2 -0
- contextsynapse/comparison.py +2 -0
- contextsynapse/config/__init__.py +10 -0
- contextsynapse/config/connectors/amfi_nav.yaml +18 -0
- contextsynapse/config/connectors/auto_sector.yaml +20 -0
- contextsynapse/config/connectors/banking_sector.yaml +20 -0
- contextsynapse/config/connectors/energy_sector.yaml +20 -0
- contextsynapse/config/connectors/fmcg_sector.yaml +20 -0
- contextsynapse/config/connectors/nsdl_fpi.yaml +9 -0
- contextsynapse/config/connectors/nse_price.yaml +61 -0
- contextsynapse/config/connectors/pharma_sector.yaml +20 -0
- contextsynapse/config/connectors/rbi_dbie.yaml +12 -0
- contextsynapse/config/context_presets/ai_research.json +25 -0
- contextsynapse/config/context_presets/chatgpt_conversations.json +19 -0
- contextsynapse/config/context_presets/claude_conversations.json +19 -0
- contextsynapse/config/context_presets/legal_compliance.json +21 -0
- contextsynapse/config/context_presets/meeting_notes.json +21 -0
- contextsynapse/config/context_presets/slack_engineering.json +21 -0
- contextsynapse/config/context_presets/tech_climate.json +24 -0
- contextsynapse/config/context_presets/toi_politics.json +25 -0
- contextsynapse/config/database_config.py +453 -0
- contextsynapse/config/deployment.py +221 -0
- contextsynapse/config/gpt_action_schema.json +164 -0
- contextsynapse/config/indicators/india_macro.yaml +213 -0
- contextsynapse/config/logging_config.py +88 -0
- contextsynapse/config/mode_config.py +223 -0
- contextsynapse/config/schemas/api_spec.yaml +48 -0
- contextsynapse/config/schemas/architecture_doc.yaml +51 -0
- contextsynapse/config/schemas/chat_history.yaml +90 -0
- contextsynapse/config/schemas/chatgpt_conversation.yaml +101 -0
- contextsynapse/config/schemas/claude_conversation.yaml +148 -0
- contextsynapse/config/schemas/contract.yaml +48 -0
- contextsynapse/config/schemas/conversation.yaml +167 -0
- contextsynapse/config/schemas/database.yaml +74 -0
- contextsynapse/config/schemas/decision.yaml +72 -0
- contextsynapse/config/schemas/ecommerce.yaml +56 -0
- contextsynapse/config/schemas/education.yaml +42 -0
- contextsynapse/config/schemas/healthcare.yaml +133 -0
- contextsynapse/config/schemas/hr_document.yaml +48 -0
- contextsynapse/config/schemas/invoice.yaml +40 -0
- contextsynapse/config/schemas/knowledge_base.yaml +75 -0
- contextsynapse/config/schemas/legal.yaml +42 -0
- contextsynapse/config/schemas/marketing_content.yaml +48 -0
- contextsynapse/config/schemas/meeting_notes.yaml +51 -0
- contextsynapse/config/schemas/news_article.yaml +61 -0
- contextsynapse/config/schemas/real_estate.yaml +49 -0
- contextsynapse/config/schemas/requirements_doc.yaml +48 -0
- contextsynapse/config/schemas/research_paper.yaml +56 -0
- contextsynapse/config/schemas/resume.yaml +49 -0
- contextsynapse/config/schemas/retail.yaml +42 -0
- contextsynapse/config/schemas/rule_meta.yaml +173 -0
- contextsynapse/config/schemas/rules.yaml +72 -0
- contextsynapse/config/schemas/screener_meta.yaml +236 -0
- contextsynapse/config/schemas/sdlc.yaml +103 -0
- contextsynapse/config/schemas/session_graph.yaml +172 -0
- contextsynapse/config/schemas/support_ticket.yaml +48 -0
- contextsynapse/config/schemas/web.yaml +64 -0
- contextsynapse/config/sensors/earnings_calendar.yaml +52 -0
- contextsynapse/config/sensors/global_risk.yaml +53 -0
- contextsynapse/config/sensors/government_policy.yaml +54 -0
- contextsynapse/config/sensors/supply_chain.yaml +50 -0
- contextsynapse/config/sensors/templates/behavioral.yaml +56 -0
- contextsynapse/config/sensors/templates/equity_sentiment.yaml +48 -0
- contextsynapse/config/sensors/templates/global_macro.yaml +47 -0
- contextsynapse/config/sensors/templates/market_data.yaml +118 -0
- contextsynapse/config/sensors/templates/sector_technical.yaml +47 -0
- contextsynapse/config/sensors/weather.yaml +52 -0
- contextsynapse/config/storage_strategy.py +202 -0
- contextsynapse/config/templates/competitive_intel.yaml +39 -0
- contextsynapse/config/templates/geopolitical_risk.yaml +46 -0
- contextsynapse/config/templates/market_analysis.yaml +58 -0
- contextsynapse/connectors/__init__.py +15 -0
- contextsynapse/connectors/api_router.py +121 -0
- contextsynapse/connectors/base.py +357 -0
- contextsynapse/connectors/financial/audio.py +170 -0
- contextsynapse/connectors/financial/youtube.py +272 -0
- contextsynapse/connectors/github.py +164 -0
- contextsynapse/connectors/jira.py +120 -0
- contextsynapse/connectors/kafka_connector.py +124 -0
- contextsynapse/connectors/pipeline_connector.py +747 -0
- contextsynapse/connectors/registry.py +116 -0
- contextsynapse/connectors/scheduler.py +87 -0
- contextsynapse/connectors/universal.py +360 -0
- contextsynapse/context/__init__.py +96 -0
- contextsynapse/context/__main__.py +4 -0
- contextsynapse/context/acl.py +125 -0
- contextsynapse/context/agent_card.py +201 -0
- contextsynapse/context/agent_memory.py +814 -0
- contextsynapse/context/agents.py +472 -0
- contextsynapse/context/agents_redis.py +391 -0
- contextsynapse/context/assembled.py +204 -0
- contextsynapse/context/attribution.py +113 -0
- contextsynapse/context/blob.py +184 -0
- contextsynapse/context/boundaries.py +187 -0
- contextsynapse/context/boundary.py +507 -0
- contextsynapse/context/bundle.py +155 -0
- contextsynapse/context/cli.py +519 -0
- contextsynapse/context/collaboration.py +165 -0
- contextsynapse/context/compiler.py +604 -0
- contextsynapse/context/composite.py +536 -0
- contextsynapse/context/compression.py +147 -0
- contextsynapse/context/context_manager.py +888 -0
- contextsynapse/context/context_schema.py +90 -0
- contextsynapse/context/context_schema.yaml +105 -0
- contextsynapse/context/context_units.py +891 -0
- contextsynapse/context/conversation.py +488 -0
- contextsynapse/context/dedup.py +207 -0
- contextsynapse/context/document_processor.py +698 -0
- contextsynapse/context/embedding_hooks.py +338 -0
- contextsynapse/context/execution_schema.py +274 -0
- contextsynapse/context/fan_out.py +138 -0
- contextsynapse/context/frozen.py +80 -0
- contextsynapse/context/gravity.py +227 -0
- contextsynapse/context/hub.py +1401 -0
- contextsynapse/context/ingest.py +391 -0
- contextsynapse/context/injection.py +226 -0
- contextsynapse/context/interaction_graphifier.py +562 -0
- contextsynapse/context/layers.py +574 -0
- contextsynapse/context/projection.py +1195 -0
- contextsynapse/context/promotion.py +634 -0
- contextsynapse/context/proof.py +131 -0
- contextsynapse/context/propagation.py +577 -0
- contextsynapse/context/pubsub.py +135 -0
- contextsynapse/context/quality.py +1054 -0
- contextsynapse/context/quality_tracker.py +270 -0
- contextsynapse/context/scoping.py +370 -0
- contextsynapse/context/seed.py +992 -0
- contextsynapse/context/session.py +1142 -0
- contextsynapse/context/session_graph.py +593 -0
- contextsynapse/context/session_memory.py +309 -0
- contextsynapse/context/session_resolver.py +111 -0
- contextsynapse/context/skill_learning.py +237 -0
- contextsynapse/context/smart_budget.py +129 -0
- contextsynapse/context/source_policy.py +242 -0
- contextsynapse/context/store_factory.py +53 -0
- contextsynapse/context/sync.py +648 -0
- contextsynapse/context/token.py +236 -0
- contextsynapse/context/vector_integration.py +297 -0
- contextsynapse/context/webhooks.py +194 -0
- contextsynapse/context/working_memory.py +224 -0
- contextsynapse/core/__init__.py +18 -0
- contextsynapse/core/archiver.py +237 -0
- contextsynapse/core/change_stream.py +282 -0
- contextsynapse/core/checkpoint.py +310 -0
- contextsynapse/core/cloud_storage.py +387 -0
- contextsynapse/core/context_state.py +651 -0
- contextsynapse/core/cron.py +324 -0
- contextsynapse/core/datasource.py +643 -0
- contextsynapse/core/db.py +289 -0
- contextsynapse/core/federation.py +283 -0
- contextsynapse/core/graph_coordinator.py +201 -0
- contextsynapse/core/graph_intelligence.py +388 -0
- contextsynapse/core/graph_structures.py +106 -0
- contextsynapse/core/graph_sync.py +157 -0
- contextsynapse/core/hybrid_graph_storage.py +2998 -0
- contextsynapse/core/lifecycle.py +691 -0
- contextsynapse/core/multiworker.py +378 -0
- contextsynapse/core/pruning.py +312 -0
- contextsynapse/core/redis_registry.py +524 -0
- contextsynapse/core/registry.py +1043 -0
- contextsynapse/core/registry_factory.py +51 -0
- contextsynapse/core/registry_metadata.py +294 -0
- contextsynapse/core/replay.py +354 -0
- contextsynapse/core/replication.py +339 -0
- contextsynapse/core/time_travel.py +260 -0
- contextsynapse/core/write_behind.py +152 -0
- contextsynapse/core/write_context.py +39 -0
- contextsynapse/db/__init__.py +1 -0
- contextsynapse/db/postgres.py +267 -0
- contextsynapse/db/profile.py +236 -0
- contextsynapse/db/rules.py +328 -0
- contextsynapse/demo/__init__.py +0 -0
- contextsynapse/demo/report.py +147 -0
- contextsynapse/demo/runner.py +520 -0
- contextsynapse/demo/scenario.py +165 -0
- contextsynapse/demo/session_demo.py +280 -0
- contextsynapse/demo/session_report.py +143 -0
- contextsynapse/demo/universal_runner.py +257 -0
- contextsynapse/engine/__init__.py +15 -0
- contextsynapse/engine/core.py +555 -0
- contextsynapse/extraction/__init__.py +69 -0
- contextsynapse/extraction/cli.py +274 -0
- contextsynapse/extraction/config.py +107 -0
- contextsynapse/extraction/examples/example_usage.py +118 -0
- contextsynapse/extraction/examples/sample_manifest.json +53 -0
- contextsynapse/extraction/examples/sample_normalized.json +185 -0
- contextsynapse/extraction/extract_engine.py +440 -0
- contextsynapse/extraction/extractors/__init__.py +37 -0
- contextsynapse/extraction/extractors/chat_export_extractor.py +189 -0
- contextsynapse/extraction/extractors/csv_extractor.py +83 -0
- contextsynapse/extraction/extractors/docx_extractor.py +129 -0
- contextsynapse/extraction/extractors/excel_extractor.py +152 -0
- contextsynapse/extraction/extractors/html_extractor.py +146 -0
- contextsynapse/extraction/extractors/pdf_extractor.py +635 -0
- contextsynapse/extraction/extractors/pdf_extractor_layoutparser.py +408 -0
- contextsynapse/extraction/extractors/register_extractors.py +63 -0
- contextsynapse/extraction/extractors/text_extractor.py +65 -0
- contextsynapse/extraction/extractors/txt_extractor.py +120 -0
- contextsynapse/extraction/extractors/website_extractor.py +246 -0
- contextsynapse/extraction/fact_extractor.py +236 -0
- contextsynapse/extraction/file_manager.py +353 -0
- contextsynapse/extraction/hierarchy.py +239 -0
- contextsynapse/extraction/id_generator.py +450 -0
- contextsynapse/extraction/layout_detector.py +409 -0
- contextsynapse/extraction/llm_entity_extractor.py +301 -0
- contextsynapse/extraction/normalized_store.py +480 -0
- contextsynapse/extraction/normalizer.py +594 -0
- contextsynapse/extraction/parquet_writer.py +598 -0
- contextsynapse/extraction/post_processors/__init__.py +40 -0
- contextsynapse/extraction/post_processors/column_reorganizer.py +507 -0
- contextsynapse/extraction/ray_normalization.py +233 -0
- contextsynapse/extraction/ray_runner.py +207 -0
- contextsynapse/extraction/redis_schema_registry.py +222 -0
- contextsynapse/extraction/registry.py +204 -0
- contextsynapse/extraction/schema_loader.py +663 -0
- contextsynapse/extraction/schema_registry.py +230 -0
- contextsynapse/extraction/semantic_normalizer.py +245 -0
- contextsynapse/extraction/version_manager.py +314 -0
- contextsynapse/gateway/__init__.py +24 -0
- contextsynapse/gateway/action_emitter.py +212 -0
- contextsynapse/gateway/cost_tracker.py +508 -0
- contextsynapse/gateway/gateway.py +377 -0
- contextsynapse/gateway/policy.py +303 -0
- contextsynapse/governance/__init__.py +13 -0
- contextsynapse/governance/layer.py +513 -0
- contextsynapse/ingestion/__init__.py +15 -0
- contextsynapse/ingestion/amplifier.py +288 -0
- contextsynapse/ingestion/async_ingest.py +463 -0
- contextsynapse/ingestion/chunker.py +303 -0
- contextsynapse/ingestion/chunking.py +58 -0
- contextsynapse/ingestion/cleaner.py +190 -0
- contextsynapse/ingestion/cleanse.py +252 -0
- contextsynapse/ingestion/connectors/__init__.py +38 -0
- contextsynapse/ingestion/connectors/base.py +300 -0
- contextsynapse/ingestion/connectors/chatgpt_memory.py +247 -0
- contextsynapse/ingestion/connectors/claude_memory.py +274 -0
- contextsynapse/ingestion/connectors/sap_ingestor.py +208 -0
- contextsynapse/ingestion/content_detector.py +80 -0
- contextsynapse/ingestion/content_monitor.py +502 -0
- contextsynapse/ingestion/dedup.py +106 -0
- contextsynapse/ingestion/feed.py +640 -0
- contextsynapse/ingestion/filters.py +461 -0
- contextsynapse/ingestion/graph_builder.py +705 -0
- contextsynapse/ingestion/input_classifier.py +307 -0
- contextsynapse/ingestion/job_manager.py +571 -0
- contextsynapse/ingestion/llm_extractor.py +610 -0
- contextsynapse/ingestion/orchestrator.py +116 -0
- contextsynapse/ingestion/parsers/__init__.py +19 -0
- contextsynapse/ingestion/parsers/graph_parser_registry.py +103 -0
- contextsynapse/ingestion/parsers/graphml_parser.py +141 -0
- contextsynapse/ingestion/parsers/jsonld_parser.py +171 -0
- contextsynapse/ingestion/parsers/rdf_parser.py +150 -0
- contextsynapse/ingestion/pipeline_context.py +228 -0
- contextsynapse/ingestion/pipeline_store.py +1195 -0
- contextsynapse/ingestion/queue.py +133 -0
- contextsynapse/ingestion/reprocess.py +179 -0
- contextsynapse/ingestion/scenario_router.py +224 -0
- contextsynapse/ingestion/schema_extractor.py +759 -0
- contextsynapse/ingestion/schema_validator.py +274 -0
- contextsynapse/ingestion/sdlc_ingest.py +87 -0
- contextsynapse/ingestion/smart_ingest.py +2451 -0
- contextsynapse/ingestion/source_connector.py +171 -0
- contextsynapse/ingestion/stage_executor.py +2095 -0
- contextsynapse/ingestion/stages/__init__.py +9 -0
- contextsynapse/ingestion/stages/tabular_to_graph.py +289 -0
- contextsynapse/ingestion/strategies.py +386 -0
- contextsynapse/ingestion/universal/__init__.py +4 -0
- contextsynapse/ingestion/universal/_operator_registry.py +59 -0
- contextsynapse/ingestion/universal/ingest_content.py +32 -0
- contextsynapse/ingestion/universal/operators/__init__.py +1 -0
- contextsynapse/ingestion/universal/operators/base.py +19 -0
- contextsynapse/ingestion/universal/operators/build_edges.py +75 -0
- contextsynapse/ingestion/universal/operators/cluster_topics.py +397 -0
- contextsynapse/ingestion/universal/operators/deduplicate.py +45 -0
- contextsynapse/ingestion/universal/operators/detect_signals.py +90 -0
- contextsynapse/ingestion/universal/operators/embed.py +80 -0
- contextsynapse/ingestion/universal/operators/extract_entities.py +253 -0
- contextsynapse/ingestion/universal/operators/extract_preferences.py +117 -0
- contextsynapse/ingestion/universal/operators/filter_content.py +69 -0
- contextsynapse/ingestion/universal/operators/index_bm25.py +52 -0
- contextsynapse/ingestion/universal/operators/infer_domains.py +69 -0
- contextsynapse/ingestion/universal/operators/link_cross_reference.py +210 -0
- contextsynapse/ingestion/universal/operators/parse_records.py +66 -0
- contextsynapse/ingestion/universal/operators/resolve_entities.py +261 -0
- contextsynapse/ingestion/universal/operators/scanners/__init__.py +16 -0
- contextsynapse/ingestion/universal/operators/scanners/edges.py +173 -0
- contextsynapse/ingestion/universal/operators/scanners/git.py +187 -0
- contextsynapse/ingestion/universal/operators/scanners/github.py +135 -0
- contextsynapse/ingestion/universal/operators/scanners/github_api.py +509 -0
- contextsynapse/ingestion/universal/operators/scanners/helpers.py +67 -0
- contextsynapse/ingestion/universal/operators/scanners/jira.py +65 -0
- contextsynapse/ingestion/universal/operators/scanners/llm_enrichment.py +82 -0
- contextsynapse/ingestion/universal/operators/scanners/repo.py +149 -0
- contextsynapse/ingestion/universal/operators/sdlc_scan.py +213 -0
- contextsynapse/ingestion/universal/operators/spec_scanner.py +149 -0
- contextsynapse/ingestion/universal/operators/store_documents.py +72 -0
- contextsynapse/ingestion/universal/operators/synthesize_cu.py +180 -0
- contextsynapse/ingestion/universal/operators/validate_gate.py +65 -0
- contextsynapse/ingestion/universal/parsers/__init__.py +5 -0
- contextsynapse/ingestion/universal/parsers/record_parser.py +203 -0
- contextsynapse/ingestion/universal/parsers/turn_parser.py +329 -0
- contextsynapse/ingestion/universal/shared_signals.py +161 -0
- contextsynapse/ingestion/universal/stage_executor.py +219 -0
- contextsynapse/ingestion/web_crawler.py +265 -0
- contextsynapse/intelligence/__init__.py +53 -0
- contextsynapse/intelligence/alerts.py +198 -0
- contextsynapse/intelligence/collector.py +655 -0
- contextsynapse/intelligence/comparison.py +198 -0
- contextsynapse/intelligence/config.py +56 -0
- contextsynapse/intelligence/conflict_detector.py +182 -0
- contextsynapse/intelligence/context_gaps.py +192 -0
- contextsynapse/intelligence/context_radar.py +135 -0
- contextsynapse/intelligence/correlation_engine.py +416 -0
- contextsynapse/intelligence/correlation_template.py +120 -0
- contextsynapse/intelligence/dedup.py +296 -0
- contextsynapse/intelligence/event_bus.py +91 -0
- contextsynapse/intelligence/feedback_loop.py +101 -0
- contextsynapse/intelligence/freshness.py +307 -0
- contextsynapse/intelligence/fundamental_feed.py +551 -0
- contextsynapse/intelligence/geo_data.py +170 -0
- contextsynapse/intelligence/geo_reference.py +112 -0
- contextsynapse/intelligence/graph_fusion.py +465 -0
- contextsynapse/intelligence/heuristics.py +176 -0
- contextsynapse/intelligence/impact_tracker.py +336 -0
- contextsynapse/intelligence/macro_indicators.py +319 -0
- contextsynapse/intelligence/ocr.py +104 -0
- contextsynapse/intelligence/persistence.py +267 -0
- contextsynapse/intelligence/pipeline_health.py +130 -0
- contextsynapse/intelligence/price_feed.py +221 -0
- contextsynapse/intelligence/rate_limiter.py +130 -0
- contextsynapse/intelligence/reactive.py +411 -0
- contextsynapse/intelligence/runtime_context.py +390 -0
- contextsynapse/intelligence/sentiment_decay.py +426 -0
- contextsynapse/intelligence/session.py +277 -0
- contextsynapse/intelligence/signal_hierarchy.py +438 -0
- contextsynapse/intelligence/signals.py +185 -0
- contextsynapse/intelligence/source_watcher.py +132 -0
- contextsynapse/intelligence/table_enricher.py +256 -0
- contextsynapse/intelligence/tagger.py +319 -0
- contextsynapse/intelligence/timeseries.py +209 -0
- contextsynapse/intelligence/tracker.py +318 -0
- contextsynapse/intelligence/watchdog.py +392 -0
- contextsynapse/intelligence/watchdog_manager.py +263 -0
- contextsynapse/intelligence/webhook_receiver.py +165 -0
- contextsynapse/intelligence/weight_learner.py +234 -0
- contextsynapse/llm/__init__.py +8 -0
- contextsynapse/llm/client.py +348 -0
- contextsynapse/llm/rate_limiter.py +166 -0
- contextsynapse/logging_config.py +2 -0
- contextsynapse/marketplace/__init__.py +7 -0
- contextsynapse/marketplace/registry.py +173 -0
- contextsynapse/mcp/__init__.py +11 -0
- contextsynapse/mcp/__main__.py +4 -0
- contextsynapse/mcp/auth_middleware.py +212 -0
- contextsynapse/mcp/connection_pool.py +128 -0
- contextsynapse/mcp/server.py +986 -0
- contextsynapse/mcp/session_context.py +67 -0
- contextsynapse/memory/__init__.py +34 -0
- contextsynapse/memory/engine.py +475 -0
- contextsynapse/memory/temporal.py +327 -0
- contextsynapse/metadata/__init__.py +12 -0
- contextsynapse/metadata/metadata_db.py +272 -0
- contextsynapse/metadata/metadata_query_tool.py +300 -0
- contextsynapse/metadata/metadata_tracker.py +425 -0
- contextsynapse/models/__init__.py +27 -0
- contextsynapse/models/embedding_service.py +360 -0
- contextsynapse/models/model_registry.py +228 -0
- contextsynapse/multiworker.py +2 -0
- contextsynapse/pipelines/__init__.py +1 -0
- contextsynapse/pipelines/executor.py +851 -0
- contextsynapse/pipelines/filters.py +189 -0
- contextsynapse/pipelines/models.py +176 -0
- contextsynapse/pipelines/scheduler.py +268 -0
- contextsynapse/playground/__init__.py +1 -0
- contextsynapse/playground/templates.py +85 -0
- contextsynapse/plugins/__init__.py +43 -0
- contextsynapse/plugins/api.py +66 -0
- contextsynapse/plugins/base.py +350 -0
- contextsynapse/plugins/domain_interface.py +508 -0
- contextsynapse/plugins/domain_loader.py +241 -0
- contextsynapse/plugins/loader.py +148 -0
- contextsynapse/plugins/registry.py +265 -0
- contextsynapse/project/__init__.py +11 -0
- contextsynapse/project/code_context.py +807 -0
- contextsynapse/project/connectors/__init__.py +4 -0
- contextsynapse/project/connectors/github_connector.py +113 -0
- contextsynapse/project/connectors/jira_connector.py +160 -0
- contextsynapse/project/graph.py +1023 -0
- contextsynapse/project/project_context.py +545 -0
- contextsynapse/project/scanner_registry.py +61 -0
- contextsynapse/project/schema_manager.py +322 -0
- contextsynapse/project/schemas/knowledge.yaml +59 -0
- contextsynapse/project/schemas/sdlc.yaml +369 -0
- contextsynapse/project/sdlc_schema.py +172 -0
- contextsynapse/project/spec_parser.py +85 -0
- contextsynapse/project/task_lock.py +181 -0
- contextsynapse/project/task_stream.py +203 -0
- contextsynapse/project/team_tools.py +537 -0
- contextsynapse/py.typed +0 -0
- contextsynapse/realtime/__init__.py +6 -0
- contextsynapse/realtime/collaboration.py +147 -0
- contextsynapse/rules/__init__.py +10 -0
- contextsynapse/rules/engine.py +116 -0
- contextsynapse/rules/evaluators/__init__.py +6 -0
- contextsynapse/rules/evaluators/aggregate.py +205 -0
- contextsynapse/rules/evaluators/custom.py +170 -0
- contextsynapse/rules/evaluators/pre_action.py +125 -0
- contextsynapse/rules/evaluators/temporal.py +129 -0
- contextsynapse/rules/loader.py +52 -0
- contextsynapse/rules/models.py +124 -0
- contextsynapse/rules/universal.py +393 -0
- contextsynapse/scheduler.py +229 -0
- contextsynapse/schema/__init__.py +42 -0
- contextsynapse/schema/compiler.py +252 -0
- contextsynapse/schema/composer.py +158 -0
- contextsynapse/schema/dedup.py +73 -0
- contextsynapse/schema/derivation.py +172 -0
- contextsynapse/schema/sdl.py +326 -0
- contextsynapse/schema/validation_gate.py +124 -0
- contextsynapse/sdk/__init__.py +63 -0
- contextsynapse/sdk/agent.py +214 -0
- contextsynapse/sdk/client.py +269 -0
- contextsynapse/sdk/exceptions.py +23 -0
- contextsynapse/sdk/models.py +78 -0
- contextsynapse/sdk/session.py +408 -0
- contextsynapse/sdk/tracked.py +218 -0
- contextsynapse/sdk/worker.py +266 -0
- contextsynapse/sdk/workspace_client.py +98 -0
- contextsynapse/sdk/ws.py +41 -0
- contextsynapse/search/__init__.py +20 -0
- contextsynapse/search/embedding_cache.py +140 -0
- contextsynapse/search/enhanced_search.py +152 -0
- contextsynapse/search/fulltext.py +130 -0
- contextsynapse/search/graph_search.py +634 -0
- contextsynapse/search/lmdb_index.py +1218 -0
- contextsynapse/search/nl_to_aiql.py +199 -0
- contextsynapse/search/rag.py +1346 -0
- contextsynapse/search/rag_cache.py +167 -0
- contextsynapse/search/reasoning_chain.py +231 -0
- contextsynapse/search/redis_search.py +207 -0
- contextsynapse/search/retrieval_quality.py +314 -0
- contextsynapse/search/semantic_query.py +455 -0
- contextsynapse/search/text_resolver.py +159 -0
- contextsynapse/search/whoosh_search.py +373 -0
- contextsynapse/security/__init__.py +17 -0
- contextsynapse/security/audit.py +297 -0
- contextsynapse/security/audit_logger.py +97 -0
- contextsynapse/security/audit_trail.py +270 -0
- contextsynapse/security/auth_unified.py +284 -0
- contextsynapse/security/auto_tagger.py +230 -0
- contextsynapse/security/data_security.py +218 -0
- contextsynapse/security/encryption.py +207 -0
- contextsynapse/security/identity.py +447 -0
- contextsynapse/security/jwt_identity.py +59 -0
- contextsynapse/security/middleware.py +336 -0
- contextsynapse/security/pii.py +233 -0
- contextsynapse/security/rbac.py +96 -0
- contextsynapse/security/rls.py +205 -0
- contextsynapse/security/sanitize.py +233 -0
- contextsynapse/security/scoped_encryption.py +131 -0
- contextsynapse/security/tenant.py +401 -0
- contextsynapse/shield/__init__.py +21 -0
- contextsynapse/shield/anomaly.py +56 -0
- contextsynapse/shield/permissions.py +99 -0
- contextsynapse/shield/profile.py +103 -0
- contextsynapse/shield/shield.py +108 -0
- contextsynapse/shield/trust_engine.py +69 -0
- contextsynapse/skills/__init__.py +14 -0
- contextsynapse/skills/engine.py +233 -0
- contextsynapse/skills/loader.py +59 -0
- contextsynapse/skills/models.py +139 -0
- contextsynapse/storage/__init__.py +7 -0
- contextsynapse/storage/cache.py +208 -0
- contextsynapse/storage/columnar_store_v2.py +178 -0
- contextsynapse/storage/csr_graph_storage.py +587 -0
- contextsynapse/storage/csr_store.py +388 -0
- contextsynapse/storage/document_store.py +491 -0
- contextsynapse/storage/hnsw_index.py +294 -0
- contextsynapse/storage/hybrid_store_v2.py +278 -0
- contextsynapse/storage/lmdb_graph_storage.py +366 -0
- contextsynapse/storage/migration.py +279 -0
- contextsynapse/storage/namespace_store.py +346 -0
- contextsynapse/storage/pure_graph_storage.py +185 -0
- contextsynapse/storage/redis_graph_adapter.py +186 -0
- contextsynapse/storage/redis_graph_storage.py +375 -0
- contextsynapse/storage/router/__init__.py +29 -0
- contextsynapse/storage/router/duckdb_store.py +398 -0
- contextsynapse/storage/router/factory.py +83 -0
- contextsynapse/storage/router/interface.py +125 -0
- contextsynapse/storage/router/postgres_store.py +339 -0
- contextsynapse/storage/router/resolver.py +192 -0
- contextsynapse/storage/router/router.py +300 -0
- contextsynapse/storage/single_file_storage.py +391 -0
- contextsynapse/storage/storage_manager.py +214 -0
- contextsynapse/storage/storage_query_optimizer.py +314 -0
- contextsynapse/storage/wal.py +359 -0
- contextsynapse/temporal/__init__.py +0 -0
- contextsynapse/temporal/storage.py +106 -0
- contextsynapse/tests/__init__.py +11 -0
- contextsynapse/tests/regression/__init__.py +1 -0
- contextsynapse/tests/regression/add_metadata.py +395 -0
- contextsynapse/tests/regression/add_skip_flags.py +85 -0
- contextsynapse/tests/regression/cases/test_basic_create_node.yaml +20 -0
- contextsynapse/tests/regression/cases/test_basic_select.yaml +21 -0
- contextsynapse/tests/regression/cases/test_blockchain_audit_trail.yaml +37 -0
- contextsynapse/tests/regression/cases/test_blockchain_audit_trail_filtered.yaml +39 -0
- contextsynapse/tests/regression/cases/test_blockchain_blocks_range.yaml +39 -0
- contextsynapse/tests/regression/cases/test_blockchain_get_block.yaml +35 -0
- contextsynapse/tests/regression/cases/test_blockchain_latest_block.yaml +35 -0
- contextsynapse/tests/regression/cases/test_blockchain_length.yaml +37 -0
- contextsynapse/tests/regression/cases/test_blockchain_merkle_root.yaml +37 -0
- contextsynapse/tests/regression/cases/test_blockchain_verify.yaml +35 -0
- contextsynapse/tests/regression/cases/test_blockchain_verify_block.yaml +35 -0
- contextsynapse/tests/regression/cases/test_create_edge.yaml +28 -0
- contextsynapse/tests/regression/cases/test_delete_edge_basic.yaml +29 -0
- contextsynapse/tests/regression/cases/test_delete_node_basic.yaml +29 -0
- contextsynapse/tests/regression/cases/test_evaluation_mrr.yaml +40 -0
- contextsynapse/tests/regression/cases/test_evaluation_ndcg.yaml +40 -0
- contextsynapse/tests/regression/cases/test_evaluation_precision.yaml +40 -0
- contextsynapse/tests/regression/cases/test_evaluation_recall.yaml +40 -0
- contextsynapse/tests/regression/cases/test_group_by_basic.yaml +56 -0
- contextsynapse/tests/regression/cases/test_match_node_basic.yaml +29 -0
- contextsynapse/tests/regression/cases/test_match_node_with_order_limit.yaml +31 -0
- contextsynapse/tests/regression/cases/test_namespace_switch.yaml +18 -0
- contextsynapse/tests/regression/cases/test_pipeline_cascaded.yaml +61 -0
- contextsynapse/tests/regression/cases/test_pipeline_fixed_size_chunking.yaml +48 -0
- contextsynapse/tests/regression/cases/test_pipeline_gpt4_chunking.yaml +54 -0
- contextsynapse/tests/regression/cases/test_pipeline_hybrid_indexing.yaml +57 -0
- contextsynapse/tests/regression/cases/test_pipeline_large_embedding.yaml +52 -0
- contextsynapse/tests/regression/cases/test_pipeline_paragraph_chunking.yaml +49 -0
- contextsynapse/tests/regression/cases/test_pipeline_recursive_chunking.yaml +47 -0
- contextsynapse/tests/regression/cases/test_pipeline_run_pipeline.yaml +56 -0
- contextsynapse/tests/regression/cases/test_pipeline_section_based_chunking.yaml +53 -0
- contextsynapse/tests/regression/cases/test_pipeline_semantic_chunking.yaml +51 -0
- contextsynapse/tests/regression/cases/test_pipeline_with_entity_extraction.yaml +57 -0
- contextsynapse/tests/regression/cases/test_pipeline_with_relationships.yaml +62 -0
- contextsynapse/tests/regression/cases/test_rag_evaluation.yaml +38 -0
- contextsynapse/tests/regression/cases/test_rag_graph_bfs_with_eval.yaml +48 -0
- contextsynapse/tests/regression/cases/test_rag_graph_centrality.yaml +40 -0
- contextsynapse/tests/regression/cases/test_rag_graph_centrality_eval.yaml +35 -0
- contextsynapse/tests/regression/cases/test_rag_graph_community.yaml +40 -0
- contextsynapse/tests/regression/cases/test_rag_graph_community_eval.yaml +35 -0
- contextsynapse/tests/regression/cases/test_rag_graph_dfs_with_eval.yaml +35 -0
- contextsynapse/tests/regression/cases/test_rag_graph_multi_hop_eval.yaml +35 -0
- contextsynapse/tests/regression/cases/test_rag_graph_path.yaml +40 -0
- contextsynapse/tests/regression/cases/test_rag_graph_search_basic.yaml +38 -0
- contextsynapse/tests/regression/cases/test_rag_graph_search_bfs.yaml +52 -0
- contextsynapse/tests/regression/cases/test_rag_graph_search_dfs.yaml +41 -0
- contextsynapse/tests/regression/cases/test_rag_graph_search_multi_hop.yaml +43 -0
- contextsynapse/tests/regression/cases/test_rag_graph_search_shortest_path.yaml +41 -0
- contextsynapse/tests/regression/cases/test_rag_graph_search_weighted.yaml +43 -0
- contextsynapse/tests/regression/cases/test_rag_graph_shortest_path_eval.yaml +35 -0
- contextsynapse/tests/regression/cases/test_rag_graph_traversal.yaml +30 -0
- contextsynapse/tests/regression/cases/test_rag_graph_weighted_eval.yaml +35 -0
- contextsynapse/tests/regression/cases/test_rag_hybrid_search.yaml +33 -0
- contextsynapse/tests/regression/cases/test_rag_hybrid_with_prompt_embedding.yaml +44 -0
- contextsynapse/tests/regression/cases/test_rag_keyword_search.yaml +32 -0
- contextsynapse/tests/regression/cases/test_rag_multi_hop_graph.yaml +32 -0
- contextsynapse/tests/regression/cases/test_rag_path_based.yaml +34 -0
- contextsynapse/tests/regression/cases/test_rag_profile_based.yaml +32 -0
- contextsynapse/tests/regression/cases/test_rag_vector_search.yaml +32 -0
- contextsynapse/tests/regression/cases/test_rag_weighted_graph.yaml +34 -0
- contextsynapse/tests/regression/cases/test_rag_weighted_hybrid.yaml +31 -0
- contextsynapse/tests/regression/cases/test_semantic_boundary_chunking.yaml +57 -0
- contextsynapse/tests/regression/cases/test_semantic_boundary_detection.yaml +33 -0
- contextsynapse/tests/regression/cases/test_semantic_hash_function.yaml +30 -0
- contextsynapse/tests/regression/cases/test_semantic_hash_with_model.yaml +31 -0
- contextsynapse/tests/regression/cases/test_tcs_ingestion_fixed_size.yaml +44 -0
- contextsynapse/tests/regression/cases/test_tcs_ingestion_recursive.yaml +46 -0
- contextsynapse/tests/regression/cases/test_tcs_ingestion_section.yaml +46 -0
- contextsynapse/tests/regression/cases/test_tcs_ingestion_semantic.yaml +44 -0
- contextsynapse/tests/regression/cases/test_time_travel_as_of.yaml +35 -0
- contextsynapse/tests/regression/cases/test_time_travel_at_commit.yaml +33 -0
- contextsynapse/tests/regression/cases/test_time_travel_at_timestamp.yaml +33 -0
- contextsynapse/tests/regression/cases/test_time_travel_for_system_time_all.yaml +37 -0
- contextsynapse/tests/regression/cases/test_time_travel_versions_between.yaml +39 -0
- contextsynapse/tests/regression/cases/test_traverse_basic.yaml +31 -0
- contextsynapse/tests/regression/cases/test_traverse_max_depth.yaml +34 -0
- contextsynapse/tests/regression/cases/test_update_edge_basic.yaml +29 -0
- contextsynapse/tests/regression/evaluation_metrics.py +227 -0
- contextsynapse/tests/regression/regression_runner.py +1081 -0
- contextsynapse/tests/regression/setup_regression_data.py +212 -0
- contextsynapse/tests/regression/test_basic_only.py +84 -0
- contextsynapse/tests/regression/test_namespace_creation.py +29 -0
- contextsynapse/tests/regression/test_single_fix.py +61 -0
- contextsynapse/tests/regression/test_single_query.py +20 -0
- contextsynapse/tests/regression/validate_test_syntax.py +179 -0
- contextsynapse/tests/test_advanced_features.py +347 -0
- contextsynapse/tests/test_aiql_summary.py +283 -0
- contextsynapse/tests/test_all_aiql_queries.py +948 -0
- contextsynapse/tests/test_all_create_queries.py +213 -0
- contextsynapse/tests/test_api_vs_native.py +280 -0
- contextsynapse/tests/test_chunking_dedup.py +199 -0
- contextsynapse/tests/test_connectors.py +171 -0
- contextsynapse/tests/test_edges_and_match.py +202 -0
- contextsynapse/tests/test_extraction_pipeline_integration.py +581 -0
- contextsynapse/tests/test_name_property.py +224 -0
- contextsynapse/tests/test_node_edge_metadata.py +250 -0
- contextsynapse/tests/test_playground_conn.py +114 -0
- contextsynapse/tests/test_query_cache.py +213 -0
- contextsynapse/tests/test_source_policy_auth.py +348 -0
- contextsynapse/tests/test_temporal_and_domain.py +224 -0
- contextsynapse/tests/test_time_travel_e2e.py +571 -0
- contextsynapse/tests/test_traversal_and_aggregation.py +275 -0
- contextsynapse/tools/__init__.py +36 -0
- contextsynapse/tools/a2a_tools.py +106 -0
- contextsynapse/tools/cognition_tools.py +118 -0
- contextsynapse/tools/context.py +905 -0
- contextsynapse/tools/formatting.py +92 -0
- contextsynapse/tools/gateway_tools.py +186 -0
- contextsynapse/tools/graph.py +1700 -0
- contextsynapse/tools/intelligence.py +235 -0
- contextsynapse/tools/memory.py +118 -0
- contextsynapse/tools/registry.py +373 -0
- contextsynapse/tools/shield_tools.py +159 -0
- contextsynapse/tools/tasks.py +341 -0
- contextsynapse/tools/workspace_tools.py +124 -0
- contextsynapse/utils/__init__.py +15 -0
- contextsynapse/utils/config_loader.py +198 -0
- contextsynapse/utils/env_loader.py +156 -0
- contextsynapse/utils/file_utils.py +288 -0
- contextsynapse/utils/logging_optimizer.py +119 -0
- contextsynapse/vector/__init__.py +30 -0
- contextsynapse/vector/chroma_vector_store.py +152 -0
- contextsynapse/vector/custom_vector_store.py +537 -0
- contextsynapse/vector/faiss_vector_store.py +296 -0
- contextsynapse/vector/qdrant_vector_store.py +163 -0
- contextsynapse/vector/vector_db.py +953 -0
- contextsynapse/vector/vector_db_manager.py +197 -0
- contextsynapse/workspace/__init__.py +27 -0
- contextsynapse/workspace/base.py +94 -0
- contextsynapse/workspace/git.py +228 -0
- contextsynapse/workspace/github.py +78 -0
- contextsynapse/workspace/local.py +73 -0
- contextsynapse/workspace/tools.py +222 -0
- contextsynapse-1.0.0.dist-info/METADATA +847 -0
- contextsynapse-1.0.0.dist-info/RECORD +776 -0
- contextsynapse-1.0.0.dist-info/WHEEL +5 -0
- contextsynapse-1.0.0.dist-info/entry_points.txt +4 -0
- contextsynapse-1.0.0.dist-info/licenses/LICENSE +200 -0
- contextsynapse-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ChromaDB Vector Store for AIContextDB
|
|
3
|
+
Cross-platform vector database using ChromaDB.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
from typing import List, Dict, Any, Optional
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
import chromadb
|
|
14
|
+
from chromadb.config import Settings
|
|
15
|
+
CHROMA_AVAILABLE = True
|
|
16
|
+
except ImportError:
|
|
17
|
+
CHROMA_AVAILABLE = False
|
|
18
|
+
logger.warning("ChromaDB not available. Install with: pip install chromadb")
|
|
19
|
+
|
|
20
|
+
class ChromaVectorStore:
|
|
21
|
+
"""
|
|
22
|
+
ChromaDB-based vector store.
|
|
23
|
+
|
|
24
|
+
Features:
|
|
25
|
+
- Cross-platform (Windows, Linux, Mac)
|
|
26
|
+
- Persistent storage
|
|
27
|
+
- Metadata filtering
|
|
28
|
+
- Good performance
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, dimension: int = 1536, metric: str = "cosine",
|
|
32
|
+
collection_name: str = "default", persist_directory: Optional[str] = None):
|
|
33
|
+
"""
|
|
34
|
+
Initialize ChromaDB vector store.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
dimension: Vector dimension
|
|
38
|
+
metric: Similarity metric ("cosine", "l2", "ip")
|
|
39
|
+
collection_name: Collection name
|
|
40
|
+
persist_directory: Directory to persist data
|
|
41
|
+
"""
|
|
42
|
+
if not CHROMA_AVAILABLE:
|
|
43
|
+
raise ImportError("ChromaDB not available. Install with: pip install chromadb")
|
|
44
|
+
|
|
45
|
+
self.dimension = dimension
|
|
46
|
+
self.metric = metric
|
|
47
|
+
self.collection_name = collection_name
|
|
48
|
+
|
|
49
|
+
# Initialize ChromaDB client
|
|
50
|
+
if persist_directory:
|
|
51
|
+
self.client = chromadb.PersistentClient(path=persist_directory)
|
|
52
|
+
else:
|
|
53
|
+
self.client = chromadb.Client()
|
|
54
|
+
|
|
55
|
+
# Get or create collection
|
|
56
|
+
try:
|
|
57
|
+
self.collection = self.client.get_collection(name=collection_name)
|
|
58
|
+
except:
|
|
59
|
+
self.collection = self.client.create_collection(
|
|
60
|
+
name=collection_name,
|
|
61
|
+
metadata={"hnsw:space": metric} # HNSW for fast search
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
self.vector_count = 0
|
|
65
|
+
|
|
66
|
+
def add_vectors(self, node_ids: List[str], vectors: List[List[float]],
|
|
67
|
+
metadata_list: Optional[List[Dict[str, Any]]] = None) -> bool:
|
|
68
|
+
"""Add vectors to ChromaDB."""
|
|
69
|
+
try:
|
|
70
|
+
# Prepare documents (empty for now, can add text later)
|
|
71
|
+
documents = [""] * len(node_ids)
|
|
72
|
+
|
|
73
|
+
# Prepare metadata
|
|
74
|
+
metadatas = []
|
|
75
|
+
for i, node_id in enumerate(node_ids):
|
|
76
|
+
meta = {"node_id": node_id}
|
|
77
|
+
if metadata_list and i < len(metadata_list):
|
|
78
|
+
meta.update(metadata_list[i])
|
|
79
|
+
metadatas.append(meta)
|
|
80
|
+
|
|
81
|
+
# Add to collection
|
|
82
|
+
self.collection.add(
|
|
83
|
+
ids=node_ids,
|
|
84
|
+
embeddings=vectors,
|
|
85
|
+
documents=documents,
|
|
86
|
+
metadatas=metadatas
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
self.vector_count = self.collection.count()
|
|
90
|
+
return True
|
|
91
|
+
|
|
92
|
+
except Exception as e:
|
|
93
|
+
logger.error(f"Failed to add vectors to ChromaDB: {e}")
|
|
94
|
+
return False
|
|
95
|
+
|
|
96
|
+
def search(self, query_vector: List[float], k: int = 10,
|
|
97
|
+
filter_ids: Optional[List[str]] = None) -> List[Dict[str, Any]]:
|
|
98
|
+
"""Search for similar vectors."""
|
|
99
|
+
try:
|
|
100
|
+
# Build where clause if filtering
|
|
101
|
+
where = None
|
|
102
|
+
if filter_ids:
|
|
103
|
+
where = {"node_id": {"$in": filter_ids}}
|
|
104
|
+
|
|
105
|
+
# Search
|
|
106
|
+
results = self.collection.query(
|
|
107
|
+
query_embeddings=[query_vector],
|
|
108
|
+
n_results=k,
|
|
109
|
+
where=where
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Format results
|
|
113
|
+
formatted_results = []
|
|
114
|
+
if results['ids'] and len(results['ids'][0]) > 0:
|
|
115
|
+
for i, node_id in enumerate(results['ids'][0]):
|
|
116
|
+
score = 1.0 - results['distances'][0][i] if results.get('distances') else 1.0
|
|
117
|
+
metadata = results['metadatas'][0][i] if results.get('metadatas') else {}
|
|
118
|
+
|
|
119
|
+
formatted_results.append({
|
|
120
|
+
'node_id': node_id,
|
|
121
|
+
'score': score,
|
|
122
|
+
'distance': results['distances'][0][i] if results.get('distances') else 0.0,
|
|
123
|
+
'metadata': metadata
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
return formatted_results
|
|
127
|
+
|
|
128
|
+
except Exception as e:
|
|
129
|
+
logger.error(f"ChromaDB search failed: {e}")
|
|
130
|
+
return []
|
|
131
|
+
|
|
132
|
+
def save(self, filepath: str) -> bool:
|
|
133
|
+
"""Save is automatic with ChromaDB persistent client."""
|
|
134
|
+
# ChromaDB automatically persists when using PersistentClient
|
|
135
|
+
return True
|
|
136
|
+
|
|
137
|
+
def load(self, filepath: str) -> bool:
|
|
138
|
+
"""Load is automatic with ChromaDB persistent client."""
|
|
139
|
+
# ChromaDB automatically loads when using PersistentClient
|
|
140
|
+
self.vector_count = self.collection.count()
|
|
141
|
+
return True
|
|
142
|
+
|
|
143
|
+
def get_vector_count(self) -> int:
|
|
144
|
+
"""Get number of vectors."""
|
|
145
|
+
try:
|
|
146
|
+
self.vector_count = self.collection.count()
|
|
147
|
+
return self.vector_count
|
|
148
|
+
except:
|
|
149
|
+
return 0
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Custom Vector Store for AIContextDB
|
|
3
|
+
Lightweight, cross-platform vector database using NumPy.
|
|
4
|
+
Works on Windows, Linux, and Mac without external dependencies.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
import json
|
|
9
|
+
import pickle
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import List, Dict, Any, Optional, Tuple
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
import logging
|
|
14
|
+
from collections import defaultdict
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
class CustomVectorStore:
|
|
19
|
+
"""
|
|
20
|
+
Custom vector store using NumPy for efficient similarity search.
|
|
21
|
+
|
|
22
|
+
Features:
|
|
23
|
+
- Fast similarity search using NumPy vectorized operations
|
|
24
|
+
- Approximate Nearest Neighbor (ANN) support for large-scale search
|
|
25
|
+
- Persistent storage (pickle for vectors, JSON for metadata)
|
|
26
|
+
- Cosine similarity by default
|
|
27
|
+
- Batch operations
|
|
28
|
+
- Cross-platform (works on Windows, Linux, Mac)
|
|
29
|
+
- No external dependencies beyond NumPy
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, dimension: int = 1536, metric: str = "cosine", use_ann: bool = True, ann_algorithm: str = "lsh"):
|
|
33
|
+
"""
|
|
34
|
+
Initialize custom vector store.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
dimension: Vector dimension (e.g., 1536, 3072)
|
|
38
|
+
metric: Similarity metric ("cosine", "euclidean", "dot")
|
|
39
|
+
use_ann: Whether to use Approximate Nearest Neighbor (faster for large datasets)
|
|
40
|
+
ann_algorithm: ANN algorithm ("lsh", "random_projection", "exact")
|
|
41
|
+
"""
|
|
42
|
+
self.dimension = dimension
|
|
43
|
+
self.metric = metric
|
|
44
|
+
self.use_ann = use_ann
|
|
45
|
+
self.ann_algorithm = ann_algorithm
|
|
46
|
+
|
|
47
|
+
# Store vectors as numpy array (n_vectors x dimension)
|
|
48
|
+
self.vectors: Optional[np.ndarray] = None
|
|
49
|
+
|
|
50
|
+
# Metadata storage: map node_id to index position and metadata
|
|
51
|
+
self.id_to_index: Dict[str, int] = {} # node_id -> index position
|
|
52
|
+
self.index_to_id: Dict[int, str] = {} # index position -> node_id
|
|
53
|
+
self.metadata: Dict[str, Dict[str, Any]] = {} # node_id -> metadata
|
|
54
|
+
|
|
55
|
+
# ANN structures
|
|
56
|
+
self.ann_index = None # ANN index structure
|
|
57
|
+
self.ann_threshold = 1000 # Use ANN if more than this many vectors
|
|
58
|
+
|
|
59
|
+
self.vector_count = 0
|
|
60
|
+
|
|
61
|
+
def add_vectors(self, node_ids: List[str], vectors: List[List[float]],
|
|
62
|
+
metadata_list: Optional[List[Dict[str, Any]]] = None) -> bool:
|
|
63
|
+
"""
|
|
64
|
+
Add vectors to the store.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
node_ids: List of node IDs
|
|
68
|
+
vectors: List of embedding vectors (each is a list of floats)
|
|
69
|
+
metadata_list: Optional list of metadata dicts
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
True if successful
|
|
73
|
+
"""
|
|
74
|
+
if len(node_ids) != len(vectors):
|
|
75
|
+
raise ValueError(f"node_ids ({len(node_ids)}) and vectors ({len(vectors)}) must have same length")
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
# Convert to numpy array
|
|
79
|
+
new_vectors = np.array(vectors, dtype=np.float32)
|
|
80
|
+
|
|
81
|
+
# Validate dimensions
|
|
82
|
+
if new_vectors.shape[1] != self.dimension:
|
|
83
|
+
raise ValueError(f"Vector dimension {new_vectors.shape[1]} doesn't match store dimension {self.dimension}")
|
|
84
|
+
|
|
85
|
+
# Normalize for cosine similarity
|
|
86
|
+
if self.metric == "cosine":
|
|
87
|
+
# Normalize each vector to unit length
|
|
88
|
+
norms = np.linalg.norm(new_vectors, axis=1, keepdims=True)
|
|
89
|
+
norms[norms == 0] = 1 # Avoid division by zero
|
|
90
|
+
new_vectors = new_vectors / norms
|
|
91
|
+
|
|
92
|
+
# Append to existing vectors or create new array
|
|
93
|
+
if self.vectors is None:
|
|
94
|
+
self.vectors = new_vectors
|
|
95
|
+
else:
|
|
96
|
+
self.vectors = np.vstack([self.vectors, new_vectors])
|
|
97
|
+
|
|
98
|
+
# Store metadata
|
|
99
|
+
start_index = self.vector_count
|
|
100
|
+
for i, node_id in enumerate(node_ids):
|
|
101
|
+
index_pos = start_index + i
|
|
102
|
+
self.id_to_index[node_id] = index_pos
|
|
103
|
+
self.index_to_id[index_pos] = node_id
|
|
104
|
+
|
|
105
|
+
if metadata_list and i < len(metadata_list):
|
|
106
|
+
self.metadata[node_id] = metadata_list[i]
|
|
107
|
+
else:
|
|
108
|
+
self.metadata[node_id] = {}
|
|
109
|
+
|
|
110
|
+
self.vector_count = len(self.vectors)
|
|
111
|
+
|
|
112
|
+
# Rebuild ANN index if using ANN
|
|
113
|
+
if self.use_ann and self.vector_count > self.ann_threshold:
|
|
114
|
+
self.ann_index = None # Force rebuild
|
|
115
|
+
self._build_lsh_index()
|
|
116
|
+
|
|
117
|
+
return True
|
|
118
|
+
|
|
119
|
+
except Exception as e:
|
|
120
|
+
logger.error(f"Failed to add vectors: {e}")
|
|
121
|
+
import traceback
|
|
122
|
+
logger.error(traceback.format_exc())
|
|
123
|
+
return False
|
|
124
|
+
|
|
125
|
+
def search(self, query_vector: List[float], k: int = 10,
|
|
126
|
+
filter_ids: Optional[List[str]] = None) -> List[Dict[str, Any]]:
|
|
127
|
+
"""
|
|
128
|
+
Search for similar vectors using exact or approximate nearest neighbor.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
query_vector: Query embedding vector
|
|
132
|
+
k: Number of results to return
|
|
133
|
+
filter_ids: Optional list of node IDs to filter by
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
List of results with node_id, score, and metadata
|
|
137
|
+
"""
|
|
138
|
+
if self.vector_count == 0 or self.vectors is None:
|
|
139
|
+
return []
|
|
140
|
+
|
|
141
|
+
try:
|
|
142
|
+
# Use ANN for large datasets, exact search for small ones
|
|
143
|
+
use_ann_search = self.use_ann and self.vector_count > self.ann_threshold
|
|
144
|
+
|
|
145
|
+
if use_ann_search:
|
|
146
|
+
return self._search_ann(query_vector, k, filter_ids)
|
|
147
|
+
else:
|
|
148
|
+
return self._search_exact(query_vector, k, filter_ids)
|
|
149
|
+
|
|
150
|
+
except Exception as e:
|
|
151
|
+
logger.error(f"Search failed: {e}")
|
|
152
|
+
import traceback
|
|
153
|
+
logger.error(traceback.format_exc())
|
|
154
|
+
return []
|
|
155
|
+
|
|
156
|
+
def _search_exact(self, query_vector: List[float], k: int = 10,
|
|
157
|
+
filter_ids: Optional[List[str]] = None) -> List[Dict[str, Any]]:
|
|
158
|
+
"""Exact nearest neighbor search (brute force)."""
|
|
159
|
+
# Convert query to numpy array
|
|
160
|
+
query = np.array([query_vector], dtype=np.float32)
|
|
161
|
+
|
|
162
|
+
# Normalize for cosine similarity
|
|
163
|
+
if self.metric == "cosine":
|
|
164
|
+
norm = np.linalg.norm(query)
|
|
165
|
+
if norm > 0:
|
|
166
|
+
query = query / norm
|
|
167
|
+
|
|
168
|
+
# Calculate similarities using vectorized operations
|
|
169
|
+
if self.metric == "cosine" or self.metric == "dot":
|
|
170
|
+
# Cosine similarity: dot product of normalized vectors
|
|
171
|
+
similarities = np.dot(self.vectors, query.T).flatten()
|
|
172
|
+
elif self.metric == "euclidean":
|
|
173
|
+
# Euclidean distance: lower is better, so we'll convert to similarity
|
|
174
|
+
distances = np.linalg.norm(self.vectors - query, axis=1)
|
|
175
|
+
similarities = 1.0 / (1.0 + distances) # Convert distance to similarity
|
|
176
|
+
else:
|
|
177
|
+
raise ValueError(f"Unsupported metric: {self.metric}")
|
|
178
|
+
|
|
179
|
+
# Get top-k indices
|
|
180
|
+
k = min(k, self.vector_count)
|
|
181
|
+
top_indices = np.argsort(similarities)[::-1][:k] # Sort descending, take top k
|
|
182
|
+
|
|
183
|
+
results = []
|
|
184
|
+
for idx in top_indices:
|
|
185
|
+
node_id = self.index_to_id.get(int(idx))
|
|
186
|
+
if node_id is None:
|
|
187
|
+
continue
|
|
188
|
+
|
|
189
|
+
# Apply filter if provided
|
|
190
|
+
if filter_ids and node_id not in filter_ids:
|
|
191
|
+
continue
|
|
192
|
+
|
|
193
|
+
score = float(similarities[idx])
|
|
194
|
+
|
|
195
|
+
results.append({
|
|
196
|
+
'node_id': node_id,
|
|
197
|
+
'score': score,
|
|
198
|
+
'distance': float(1.0 - score) if self.metric == "cosine" else float(1.0 / (1.0 + score)),
|
|
199
|
+
'metadata': self.metadata.get(node_id, {})
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
return results
|
|
203
|
+
|
|
204
|
+
def _search_ann(self, query_vector: List[float], k: int = 10,
|
|
205
|
+
filter_ids: Optional[List[str]] = None) -> List[Dict[str, Any]]:
|
|
206
|
+
"""
|
|
207
|
+
Approximate Nearest Neighbor search.
|
|
208
|
+
Uses Locality-Sensitive Hashing (LSH) or random projection for fast search.
|
|
209
|
+
"""
|
|
210
|
+
if self.ann_algorithm == "lsh":
|
|
211
|
+
return self._search_lsh(query_vector, k, filter_ids)
|
|
212
|
+
elif self.ann_algorithm == "random_projection":
|
|
213
|
+
return self._search_random_projection(query_vector, k, filter_ids)
|
|
214
|
+
else:
|
|
215
|
+
# Fallback to exact search
|
|
216
|
+
return self._search_exact(query_vector, k, filter_ids)
|
|
217
|
+
|
|
218
|
+
def _search_lsh(self, query_vector: List[float], k: int = 10,
|
|
219
|
+
filter_ids: Optional[List[str]] = None) -> List[Dict[str, Any]]:
|
|
220
|
+
"""
|
|
221
|
+
Locality-Sensitive Hashing (LSH) for approximate search.
|
|
222
|
+
Simple implementation using random hyperplanes.
|
|
223
|
+
"""
|
|
224
|
+
# For LSH, we use a simple approach: random projection + hash buckets
|
|
225
|
+
# This is a simplified version - for production, consider using a library
|
|
226
|
+
|
|
227
|
+
# Build LSH index if not exists
|
|
228
|
+
if self.ann_index is None:
|
|
229
|
+
self._build_lsh_index()
|
|
230
|
+
|
|
231
|
+
# Convert query to numpy array
|
|
232
|
+
query = np.array(query_vector, dtype=np.float32)
|
|
233
|
+
|
|
234
|
+
# Normalize for cosine similarity
|
|
235
|
+
if self.metric == "cosine":
|
|
236
|
+
norm = np.linalg.norm(query)
|
|
237
|
+
if norm > 0:
|
|
238
|
+
query = query / norm
|
|
239
|
+
|
|
240
|
+
# Hash query to find candidate buckets
|
|
241
|
+
query_hash = self._hash_vector(query)
|
|
242
|
+
|
|
243
|
+
# Get candidates from same or nearby buckets
|
|
244
|
+
candidates = self._get_lsh_candidates(query_hash, query, k * 3) # Get 3x candidates for refinement
|
|
245
|
+
|
|
246
|
+
# Refine candidates with exact similarity
|
|
247
|
+
if len(candidates) > 0:
|
|
248
|
+
candidate_vectors = self.vectors[candidates]
|
|
249
|
+
if self.metric == "cosine" or self.metric == "dot":
|
|
250
|
+
similarities = np.dot(candidate_vectors, query).flatten()
|
|
251
|
+
else:
|
|
252
|
+
distances = np.linalg.norm(candidate_vectors - query, axis=1)
|
|
253
|
+
similarities = 1.0 / (1.0 + distances)
|
|
254
|
+
|
|
255
|
+
# Get top-k from candidates
|
|
256
|
+
top_candidate_indices = np.argsort(similarities)[::-1][:k]
|
|
257
|
+
top_indices = candidates[top_candidate_indices]
|
|
258
|
+
else:
|
|
259
|
+
# Fallback to exact search if no candidates
|
|
260
|
+
return self._search_exact(query_vector, k, filter_ids)
|
|
261
|
+
|
|
262
|
+
# Format results
|
|
263
|
+
results = []
|
|
264
|
+
for idx in top_indices:
|
|
265
|
+
node_id = self.index_to_id.get(int(idx))
|
|
266
|
+
if node_id is None:
|
|
267
|
+
continue
|
|
268
|
+
|
|
269
|
+
if filter_ids and node_id not in filter_ids:
|
|
270
|
+
continue
|
|
271
|
+
|
|
272
|
+
# Calculate exact similarity for result
|
|
273
|
+
if self.metric == "cosine" or self.metric == "dot":
|
|
274
|
+
score = float(np.dot(self.vectors[idx], query))
|
|
275
|
+
else:
|
|
276
|
+
dist = np.linalg.norm(self.vectors[idx] - query)
|
|
277
|
+
score = float(1.0 / (1.0 + dist))
|
|
278
|
+
|
|
279
|
+
results.append({
|
|
280
|
+
'node_id': node_id,
|
|
281
|
+
'score': score,
|
|
282
|
+
'distance': float(1.0 - score) if self.metric == "cosine" else float(1.0 / (1.0 + score)),
|
|
283
|
+
'metadata': self.metadata.get(node_id, {})
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
return results
|
|
287
|
+
|
|
288
|
+
def _build_lsh_index(self):
|
|
289
|
+
"""Build LSH index for approximate search."""
|
|
290
|
+
if self.vectors is None or len(self.vectors) == 0:
|
|
291
|
+
return
|
|
292
|
+
|
|
293
|
+
# Simple LSH: use random hyperplanes to create hash buckets
|
|
294
|
+
num_hyperplanes = min(10, self.dimension // 10) # Number of random hyperplanes
|
|
295
|
+
np.random.seed(42) # For reproducibility
|
|
296
|
+
|
|
297
|
+
# Generate random hyperplanes
|
|
298
|
+
self.lsh_hyperplanes = np.random.randn(num_hyperplanes, self.dimension).astype(np.float32)
|
|
299
|
+
|
|
300
|
+
# Normalize hyperplanes
|
|
301
|
+
norms = np.linalg.norm(self.lsh_hyperplanes, axis=1, keepdims=True)
|
|
302
|
+
norms[norms == 0] = 1
|
|
303
|
+
self.lsh_hyperplanes = self.lsh_hyperplanes / norms
|
|
304
|
+
|
|
305
|
+
# Build hash buckets
|
|
306
|
+
self.lsh_buckets: Dict[int, List[int]] = defaultdict(list)
|
|
307
|
+
|
|
308
|
+
for idx in range(len(self.vectors)):
|
|
309
|
+
vector = self.vectors[idx]
|
|
310
|
+
if self.metric == "cosine":
|
|
311
|
+
# Normalize vector
|
|
312
|
+
norm = np.linalg.norm(vector)
|
|
313
|
+
if norm > 0:
|
|
314
|
+
vector = vector / norm
|
|
315
|
+
|
|
316
|
+
# Hash vector
|
|
317
|
+
hash_val = self._hash_vector(vector)
|
|
318
|
+
self.lsh_buckets[hash_val].append(idx)
|
|
319
|
+
|
|
320
|
+
self.ann_index = "lsh" # Mark as built
|
|
321
|
+
|
|
322
|
+
def _hash_vector(self, vector: np.ndarray) -> int:
|
|
323
|
+
"""Hash vector using hyperplanes."""
|
|
324
|
+
if not hasattr(self, 'lsh_hyperplanes'):
|
|
325
|
+
return 0
|
|
326
|
+
|
|
327
|
+
# Project vector onto hyperplanes and create binary hash
|
|
328
|
+
projections = np.dot(self.lsh_hyperplanes, vector)
|
|
329
|
+
binary_hash = (projections > 0).astype(int)
|
|
330
|
+
|
|
331
|
+
# Convert binary array to integer hash
|
|
332
|
+
hash_int = 0
|
|
333
|
+
for bit in binary_hash:
|
|
334
|
+
hash_int = (hash_int << 1) | bit
|
|
335
|
+
|
|
336
|
+
return hash_int
|
|
337
|
+
|
|
338
|
+
def _get_lsh_candidates(self, query_hash: int, query: np.ndarray, max_candidates: int = 100) -> np.ndarray:
|
|
339
|
+
"""Get candidate indices from LSH buckets."""
|
|
340
|
+
candidates = set()
|
|
341
|
+
|
|
342
|
+
# Get candidates from same bucket
|
|
343
|
+
if query_hash in self.lsh_buckets:
|
|
344
|
+
candidates.update(self.lsh_buckets[query_hash])
|
|
345
|
+
|
|
346
|
+
# Get candidates from nearby buckets (Hamming distance 1)
|
|
347
|
+
if hasattr(self, 'lsh_hyperplanes'):
|
|
348
|
+
num_bits = len(self.lsh_hyperplanes)
|
|
349
|
+
for i in range(num_bits):
|
|
350
|
+
# Flip bit i
|
|
351
|
+
nearby_hash = query_hash ^ (1 << (num_bits - 1 - i))
|
|
352
|
+
if nearby_hash in self.lsh_buckets:
|
|
353
|
+
candidates.update(self.lsh_buckets[nearby_hash])
|
|
354
|
+
|
|
355
|
+
# Limit candidates
|
|
356
|
+
candidates_list = list(candidates)[:max_candidates]
|
|
357
|
+
return np.array(candidates_list, dtype=int) if candidates_list else np.array([], dtype=int)
|
|
358
|
+
|
|
359
|
+
def _search_random_projection(self, query_vector: List[float], k: int = 10,
|
|
360
|
+
filter_ids: Optional[List[str]] = None) -> List[Dict[str, Any]]:
|
|
361
|
+
"""
|
|
362
|
+
Random projection-based approximate search.
|
|
363
|
+
Projects vectors to lower dimension for faster search.
|
|
364
|
+
"""
|
|
365
|
+
# For now, fallback to exact search
|
|
366
|
+
# Can be enhanced with actual random projection
|
|
367
|
+
return self._search_exact(query_vector, k, filter_ids)
|
|
368
|
+
|
|
369
|
+
def save(self, filepath: str) -> bool:
|
|
370
|
+
"""
|
|
371
|
+
Save vectors and metadata to disk.
|
|
372
|
+
|
|
373
|
+
Args:
|
|
374
|
+
filepath: Path to save (without extension)
|
|
375
|
+
"""
|
|
376
|
+
try:
|
|
377
|
+
path = Path(filepath)
|
|
378
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
379
|
+
|
|
380
|
+
# Save vectors as numpy file (efficient binary format)
|
|
381
|
+
vectors_file = path.parent / (path.name + "_vectors.npy")
|
|
382
|
+
if self.vectors is not None:
|
|
383
|
+
np.save(str(vectors_file), self.vectors)
|
|
384
|
+
else:
|
|
385
|
+
# Create empty array to save
|
|
386
|
+
np.save(str(vectors_file), np.array([], dtype=np.float32).reshape(0, self.dimension))
|
|
387
|
+
|
|
388
|
+
# Save metadata as pickle (preserves dict structure)
|
|
389
|
+
metadata_file = path.parent / (path.name + "_metadata.pkl")
|
|
390
|
+
with open(metadata_file, 'wb') as f:
|
|
391
|
+
pickle.dump({
|
|
392
|
+
'id_to_index': self.id_to_index,
|
|
393
|
+
'index_to_id': self.index_to_id,
|
|
394
|
+
'metadata': self.metadata,
|
|
395
|
+
'vector_count': self.vector_count,
|
|
396
|
+
'total_vectors': self.vector_count, # Add alias for compatibility
|
|
397
|
+
'count': self.vector_count, # Add another alias
|
|
398
|
+
'dimension': self.dimension,
|
|
399
|
+
'metric': self.metric,
|
|
400
|
+
'use_ann': self.use_ann,
|
|
401
|
+
'ann_algorithm': self.ann_algorithm,
|
|
402
|
+
'lsh_hyperplanes': getattr(self, 'lsh_hyperplanes', None),
|
|
403
|
+
'lsh_buckets': dict(getattr(self, 'lsh_buckets', {}))
|
|
404
|
+
}, f)
|
|
405
|
+
|
|
406
|
+
logger.info(f"Saved vector store to {path} ({self.vector_count} vectors)")
|
|
407
|
+
return True
|
|
408
|
+
|
|
409
|
+
except Exception as e:
|
|
410
|
+
logger.error(f"Failed to save vector store: {e}")
|
|
411
|
+
import traceback
|
|
412
|
+
logger.error(traceback.format_exc())
|
|
413
|
+
return False
|
|
414
|
+
|
|
415
|
+
def load(self, filepath: str) -> bool:
|
|
416
|
+
"""
|
|
417
|
+
Load vectors and metadata from disk.
|
|
418
|
+
|
|
419
|
+
Args:
|
|
420
|
+
filepath: Path to load from (without extension)
|
|
421
|
+
"""
|
|
422
|
+
try:
|
|
423
|
+
path = Path(filepath)
|
|
424
|
+
|
|
425
|
+
# Load vectors
|
|
426
|
+
vectors_file = path.parent / (path.name + "_vectors.npy")
|
|
427
|
+
if not vectors_file.exists():
|
|
428
|
+
logger.warning(f"Vectors file not found: {vectors_file}")
|
|
429
|
+
return False
|
|
430
|
+
|
|
431
|
+
self.vectors = np.load(str(vectors_file))
|
|
432
|
+
|
|
433
|
+
# Load metadata
|
|
434
|
+
metadata_file = path.parent / (path.name + "_metadata.pkl")
|
|
435
|
+
if not metadata_file.exists():
|
|
436
|
+
logger.warning(f"Metadata file not found: {metadata_file}")
|
|
437
|
+
return False
|
|
438
|
+
|
|
439
|
+
with open(metadata_file, 'rb') as f:
|
|
440
|
+
data = pickle.load(f)
|
|
441
|
+
self.id_to_index = data.get('id_to_index', {})
|
|
442
|
+
self.index_to_id = data.get('index_to_id', {})
|
|
443
|
+
self.metadata = data.get('metadata', {})
|
|
444
|
+
self.vector_count = data.get('vector_count', 0)
|
|
445
|
+
self.dimension = data.get('dimension', self.dimension)
|
|
446
|
+
self.metric = data.get('metric', self.metric)
|
|
447
|
+
self.use_ann = data.get('use_ann', self.use_ann)
|
|
448
|
+
self.ann_algorithm = data.get('ann_algorithm', self.ann_algorithm)
|
|
449
|
+
|
|
450
|
+
# Restore LSH index if available
|
|
451
|
+
if 'lsh_hyperplanes' in data and data['lsh_hyperplanes'] is not None:
|
|
452
|
+
self.lsh_hyperplanes = data['lsh_hyperplanes']
|
|
453
|
+
self.lsh_buckets = defaultdict(list, data.get('lsh_buckets', {}))
|
|
454
|
+
self.ann_index = "lsh"
|
|
455
|
+
|
|
456
|
+
# Validate
|
|
457
|
+
if self.vectors is not None and len(self.vectors) != self.vector_count:
|
|
458
|
+
logger.warning(f"Vector count mismatch: {len(self.vectors)} vectors vs {self.vector_count} metadata entries")
|
|
459
|
+
self.vector_count = len(self.vectors)
|
|
460
|
+
|
|
461
|
+
logger.info(f"Loaded vector store from {vectors_file} ({self.vector_count} vectors)")
|
|
462
|
+
return True
|
|
463
|
+
|
|
464
|
+
except Exception as e:
|
|
465
|
+
logger.error(f"Failed to load vector store: {e}")
|
|
466
|
+
import traceback
|
|
467
|
+
logger.error(traceback.format_exc())
|
|
468
|
+
return False
|
|
469
|
+
|
|
470
|
+
def get_vector_count(self) -> int:
|
|
471
|
+
"""Get number of vectors in store."""
|
|
472
|
+
return self.vector_count
|
|
473
|
+
|
|
474
|
+
def remove_vectors(self, node_ids: List[str]) -> bool:
|
|
475
|
+
"""
|
|
476
|
+
Remove vectors from store.
|
|
477
|
+
Note: This rebuilds the index, which can be slow for large stores.
|
|
478
|
+
"""
|
|
479
|
+
if not node_ids:
|
|
480
|
+
return True
|
|
481
|
+
|
|
482
|
+
try:
|
|
483
|
+
if self.vectors is None:
|
|
484
|
+
return True
|
|
485
|
+
|
|
486
|
+
# Get indices to keep
|
|
487
|
+
indices_to_keep = []
|
|
488
|
+
new_id_to_index = {}
|
|
489
|
+
new_index_to_id = {}
|
|
490
|
+
new_metadata = {}
|
|
491
|
+
|
|
492
|
+
new_idx = 0
|
|
493
|
+
for old_idx in range(self.vector_count):
|
|
494
|
+
node_id = self.index_to_id.get(old_idx)
|
|
495
|
+
if node_id and node_id not in node_ids:
|
|
496
|
+
indices_to_keep.append(old_idx)
|
|
497
|
+
new_id_to_index[node_id] = new_idx
|
|
498
|
+
new_index_to_id[new_idx] = node_id
|
|
499
|
+
new_metadata[node_id] = self.metadata.get(node_id, {})
|
|
500
|
+
new_idx += 1
|
|
501
|
+
|
|
502
|
+
# Rebuild vectors array
|
|
503
|
+
if indices_to_keep:
|
|
504
|
+
self.vectors = self.vectors[indices_to_keep]
|
|
505
|
+
else:
|
|
506
|
+
self.vectors = None
|
|
507
|
+
|
|
508
|
+
# Update metadata
|
|
509
|
+
self.id_to_index = new_id_to_index
|
|
510
|
+
self.index_to_id = new_index_to_id
|
|
511
|
+
self.metadata = new_metadata
|
|
512
|
+
self.vector_count = len(indices_to_keep) if indices_to_keep else 0
|
|
513
|
+
|
|
514
|
+
return True
|
|
515
|
+
|
|
516
|
+
except Exception as e:
|
|
517
|
+
logger.error(f"Failed to remove vectors: {e}")
|
|
518
|
+
return False
|
|
519
|
+
|
|
520
|
+
def get_vector(self, node_id: str) -> Optional[np.ndarray]:
|
|
521
|
+
"""Get vector for a specific node ID."""
|
|
522
|
+
if self.vectors is None:
|
|
523
|
+
return None
|
|
524
|
+
|
|
525
|
+
idx = self.id_to_index.get(node_id)
|
|
526
|
+
if idx is None:
|
|
527
|
+
return None
|
|
528
|
+
|
|
529
|
+
return self.vectors[idx]
|
|
530
|
+
|
|
531
|
+
def batch_add(self, batch_size: int = 100) -> bool:
|
|
532
|
+
"""
|
|
533
|
+
Prepare for batch operations.
|
|
534
|
+
This is a placeholder for future batch optimization.
|
|
535
|
+
"""
|
|
536
|
+
return True
|
|
537
|
+
|