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,235 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Graph Statistics Collector
|
|
3
|
+
===========================
|
|
4
|
+
Collects graph statistics for the AIQL query optimizer.
|
|
5
|
+
Used by the cost estimator to choose between full scan, label index, etc.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
from typing import Any, Dict, Optional, Set
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class GraphStatistics:
|
|
19
|
+
"""Statistics about a graph namespace for query optimization."""
|
|
20
|
+
total_nodes: int = 0
|
|
21
|
+
total_edges: int = 0
|
|
22
|
+
node_count_by_label: Dict[str, int] = field(default_factory=dict)
|
|
23
|
+
edge_count_by_type: Dict[str, int] = field(default_factory=dict)
|
|
24
|
+
label_index_available: bool = False
|
|
25
|
+
|
|
26
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
27
|
+
return {
|
|
28
|
+
"total_nodes": self.total_nodes,
|
|
29
|
+
"total_edges": self.total_edges,
|
|
30
|
+
"node_count_by_label": self.node_count_by_label,
|
|
31
|
+
"edge_count_by_type": self.edge_count_by_type,
|
|
32
|
+
"label_index_available": self.label_index_available,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass
|
|
37
|
+
class CostEstimate:
|
|
38
|
+
"""Cost estimate for a query execution plan."""
|
|
39
|
+
scan_type: str # "full_scan" | "label_index" | "property_filter"
|
|
40
|
+
estimated_rows: int
|
|
41
|
+
estimated_cost: float
|
|
42
|
+
explanation: str
|
|
43
|
+
|
|
44
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
45
|
+
return {
|
|
46
|
+
"scan_type": self.scan_type,
|
|
47
|
+
"estimated_rows": self.estimated_rows,
|
|
48
|
+
"estimated_cost": round(self.estimated_cost, 4),
|
|
49
|
+
"explanation": self.explanation,
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass
|
|
54
|
+
class QueryPlan:
|
|
55
|
+
"""A planned query execution strategy."""
|
|
56
|
+
scan_type: str
|
|
57
|
+
label_filter: Optional[str] = None
|
|
58
|
+
property_filters: Dict[str, Any] = field(default_factory=dict)
|
|
59
|
+
cost: Optional[CostEstimate] = None
|
|
60
|
+
use_vector: bool = False
|
|
61
|
+
use_bm25: bool = False
|
|
62
|
+
|
|
63
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
64
|
+
return {
|
|
65
|
+
"scan_type": self.scan_type,
|
|
66
|
+
"label_filter": self.label_filter,
|
|
67
|
+
"property_filters": self.property_filters,
|
|
68
|
+
"cost": self.cost.to_dict() if self.cost else None,
|
|
69
|
+
"use_vector": self.use_vector,
|
|
70
|
+
"use_bm25": self.use_bm25,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class GraphStatisticsCollector:
|
|
75
|
+
"""Collects statistics from a graph for query optimization."""
|
|
76
|
+
|
|
77
|
+
def __init__(self, graph_storage=None):
|
|
78
|
+
self._graph = graph_storage
|
|
79
|
+
|
|
80
|
+
def collect(self, graph=None) -> GraphStatistics:
|
|
81
|
+
"""Collect statistics from the graph.
|
|
82
|
+
|
|
83
|
+
Uses get_statistics() if available (fast path via label index),
|
|
84
|
+
otherwise falls back to scanning.
|
|
85
|
+
"""
|
|
86
|
+
db = graph or self._graph
|
|
87
|
+
if not db:
|
|
88
|
+
return GraphStatistics()
|
|
89
|
+
|
|
90
|
+
# Fast path: use built-in statistics
|
|
91
|
+
if hasattr(db, "get_statistics"):
|
|
92
|
+
try:
|
|
93
|
+
raw = db.get_statistics()
|
|
94
|
+
return GraphStatistics(
|
|
95
|
+
total_nodes=raw.get("total_nodes", 0),
|
|
96
|
+
total_edges=raw.get("total_edges", 0),
|
|
97
|
+
node_count_by_label=raw.get("node_count_by_label", {}),
|
|
98
|
+
edge_count_by_type=raw.get("edge_count_by_type", {}),
|
|
99
|
+
label_index_available=raw.get("label_index_available", False),
|
|
100
|
+
)
|
|
101
|
+
except Exception as e:
|
|
102
|
+
logger.debug("get_statistics() failed, falling back to scan: %s", e)
|
|
103
|
+
|
|
104
|
+
# Slow path: count manually
|
|
105
|
+
try:
|
|
106
|
+
all_nodes = db.get_all_nodes()
|
|
107
|
+
label_counts: Dict[str, int] = {}
|
|
108
|
+
for n in all_nodes:
|
|
109
|
+
lbl = getattr(n, "label", "")
|
|
110
|
+
label_counts[lbl] = label_counts.get(lbl, 0) + 1
|
|
111
|
+
|
|
112
|
+
all_edges = db.get_all_edges()
|
|
113
|
+
edge_counts: Dict[str, int] = {}
|
|
114
|
+
for e in all_edges:
|
|
115
|
+
et = getattr(e, "label", "")
|
|
116
|
+
edge_counts[et] = edge_counts.get(et, 0) + 1
|
|
117
|
+
|
|
118
|
+
return GraphStatistics(
|
|
119
|
+
total_nodes=len(all_nodes),
|
|
120
|
+
total_edges=len(all_edges),
|
|
121
|
+
node_count_by_label=label_counts,
|
|
122
|
+
edge_count_by_type=edge_counts,
|
|
123
|
+
label_index_available=False,
|
|
124
|
+
)
|
|
125
|
+
except Exception:
|
|
126
|
+
return GraphStatistics()
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class CostEstimator:
|
|
130
|
+
"""Estimates query cost based on graph statistics."""
|
|
131
|
+
|
|
132
|
+
PER_NODE_COST = 0.001 # cost units per node scanned
|
|
133
|
+
INDEX_OVERHEAD = 0.01 # fixed overhead for index lookup
|
|
134
|
+
|
|
135
|
+
def estimate_full_scan(self, stats: GraphStatistics) -> CostEstimate:
|
|
136
|
+
"""Cost of scanning all nodes."""
|
|
137
|
+
cost = stats.total_nodes * self.PER_NODE_COST
|
|
138
|
+
return CostEstimate(
|
|
139
|
+
scan_type="full_scan",
|
|
140
|
+
estimated_rows=stats.total_nodes,
|
|
141
|
+
estimated_cost=cost,
|
|
142
|
+
explanation=f"Full scan of {stats.total_nodes} nodes",
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
def estimate_label_scan(self, stats: GraphStatistics, label: str) -> CostEstimate:
|
|
146
|
+
"""Cost of scanning nodes by label index."""
|
|
147
|
+
count = stats.node_count_by_label.get(label, stats.total_nodes)
|
|
148
|
+
cost = count * self.PER_NODE_COST + self.INDEX_OVERHEAD
|
|
149
|
+
return CostEstimate(
|
|
150
|
+
scan_type="label_index",
|
|
151
|
+
estimated_rows=count,
|
|
152
|
+
estimated_cost=cost,
|
|
153
|
+
explanation=f"Label index scan: {count} '{label}' nodes (of {stats.total_nodes} total)",
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
def estimate_property_filter(self, stats: GraphStatistics, label: str, prop: str) -> CostEstimate:
|
|
157
|
+
"""Cost of label scan + property filter."""
|
|
158
|
+
label_count = stats.node_count_by_label.get(label, stats.total_nodes)
|
|
159
|
+
# Assume property filter reduces by ~50% (heuristic)
|
|
160
|
+
estimated = max(1, label_count // 2)
|
|
161
|
+
cost = label_count * self.PER_NODE_COST + self.INDEX_OVERHEAD * 2
|
|
162
|
+
return CostEstimate(
|
|
163
|
+
scan_type="property_filter",
|
|
164
|
+
estimated_rows=estimated,
|
|
165
|
+
estimated_cost=cost,
|
|
166
|
+
explanation=f"Label index '{label}' ({label_count} nodes) + property filter on '{prop}'",
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class QueryPlanSelector:
|
|
171
|
+
"""Selects the optimal query execution plan based on cost estimates."""
|
|
172
|
+
|
|
173
|
+
def __init__(self):
|
|
174
|
+
self._estimator = CostEstimator()
|
|
175
|
+
|
|
176
|
+
def select_plan(
|
|
177
|
+
self,
|
|
178
|
+
stats: GraphStatistics,
|
|
179
|
+
label: Optional[str] = None,
|
|
180
|
+
where_props: Optional[Dict[str, Any]] = None,
|
|
181
|
+
) -> QueryPlan:
|
|
182
|
+
"""Choose the cheapest execution plan.
|
|
183
|
+
|
|
184
|
+
Decision tree:
|
|
185
|
+
1. If label provided AND label index available → label_index scan
|
|
186
|
+
2. If label provided but no index → full_scan with label filter
|
|
187
|
+
3. If no label → full_scan
|
|
188
|
+
"""
|
|
189
|
+
where_props = where_props or {}
|
|
190
|
+
|
|
191
|
+
if not label:
|
|
192
|
+
cost = self._estimator.estimate_full_scan(stats)
|
|
193
|
+
return QueryPlan(scan_type="full_scan", cost=cost)
|
|
194
|
+
|
|
195
|
+
if stats.label_index_available:
|
|
196
|
+
if where_props:
|
|
197
|
+
prop = next(iter(where_props))
|
|
198
|
+
cost = self._estimator.estimate_property_filter(stats, label, prop)
|
|
199
|
+
return QueryPlan(
|
|
200
|
+
scan_type="label_index",
|
|
201
|
+
label_filter=label,
|
|
202
|
+
property_filters=where_props,
|
|
203
|
+
cost=cost,
|
|
204
|
+
)
|
|
205
|
+
else:
|
|
206
|
+
cost = self._estimator.estimate_label_scan(stats, label)
|
|
207
|
+
return QueryPlan(
|
|
208
|
+
scan_type="label_index",
|
|
209
|
+
label_filter=label,
|
|
210
|
+
cost=cost,
|
|
211
|
+
)
|
|
212
|
+
else:
|
|
213
|
+
# No index — full scan with in-memory label filter
|
|
214
|
+
cost = self._estimator.estimate_full_scan(stats)
|
|
215
|
+
cost.explanation += f" (filtered to label '{label}' in memory)"
|
|
216
|
+
return QueryPlan(
|
|
217
|
+
scan_type="full_scan",
|
|
218
|
+
label_filter=label,
|
|
219
|
+
cost=cost,
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
@dataclass
|
|
224
|
+
class ExplainResult:
|
|
225
|
+
"""Result of EXPLAIN query — shows plan without executing."""
|
|
226
|
+
query: str
|
|
227
|
+
plan: QueryPlan
|
|
228
|
+
statistics: GraphStatistics
|
|
229
|
+
|
|
230
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
231
|
+
return {
|
|
232
|
+
"query": self.query,
|
|
233
|
+
"plan": self.plan.to_dict(),
|
|
234
|
+
"statistics": self.statistics.to_dict(),
|
|
235
|
+
}
|
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AIQL Validator - Validates semantic correctness of parsed AIQL queries
|
|
3
|
+
|
|
4
|
+
After syntax is OK, the validator ensures:
|
|
5
|
+
- Namespace exists
|
|
6
|
+
- Collection exists
|
|
7
|
+
- Tables/entities exist
|
|
8
|
+
- Columns/properties exist
|
|
9
|
+
- Data types are compatible
|
|
10
|
+
- User privileges/permissions
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from typing import Dict, List, Any, Optional
|
|
14
|
+
from enum import Enum
|
|
15
|
+
|
|
16
|
+
class ValidationError(Exception):
|
|
17
|
+
"""Custom exception for validation errors"""
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
class NodeType(str, Enum):
|
|
21
|
+
"""Valid node types"""
|
|
22
|
+
DOCUMENT = "Document"
|
|
23
|
+
CHUNK = "Chunk"
|
|
24
|
+
ENTITY = "Entity"
|
|
25
|
+
TABLE = "Table"
|
|
26
|
+
IMAGE = "Image"
|
|
27
|
+
SOUND = "Sound"
|
|
28
|
+
# Add more as needed
|
|
29
|
+
|
|
30
|
+
class ValidatorMode(str, Enum):
|
|
31
|
+
"""Validation modes"""
|
|
32
|
+
STRICT = "strict" # Fail on any error
|
|
33
|
+
PERMISSIVE = "permissive" # Warn but continue
|
|
34
|
+
AUTO_CREATE = "auto_create" # Auto-create missing resources
|
|
35
|
+
|
|
36
|
+
class AIQLValidator:
|
|
37
|
+
"""
|
|
38
|
+
Validates AIQL query semantics after syntax parsing
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(self, db_interface=None, mode=ValidatorMode.STRICT):
|
|
42
|
+
"""
|
|
43
|
+
Initialize validator
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
db_interface: Interface to AIContextDB for checking resources
|
|
47
|
+
mode: Validation mode (strict, permissive, auto_create)
|
|
48
|
+
"""
|
|
49
|
+
self.db_interface = db_interface
|
|
50
|
+
self.mode = mode
|
|
51
|
+
self.validation_errors = []
|
|
52
|
+
self.validation_warnings = []
|
|
53
|
+
|
|
54
|
+
def validate(self, parsed_ast: Dict[str, Any]) -> Dict[str, Any]:
|
|
55
|
+
"""
|
|
56
|
+
Main validation entry point
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
parsed_ast: Parsed AST from parser
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
Validation result with errors and warnings
|
|
63
|
+
"""
|
|
64
|
+
self.validation_errors = []
|
|
65
|
+
self.validation_warnings = []
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
query_type = parsed_ast.get('query_type', 'UNKNOWN')
|
|
69
|
+
|
|
70
|
+
if query_type == 'RAG':
|
|
71
|
+
return self._validate_rag_query(parsed_ast)
|
|
72
|
+
elif query_type == 'PIPELINE':
|
|
73
|
+
return self._validate_pipeline_query(parsed_ast)
|
|
74
|
+
elif query_type == 'RETRIEVE':
|
|
75
|
+
return self._validate_retrieve_query(parsed_ast)
|
|
76
|
+
elif query_type == 'UPDATE':
|
|
77
|
+
return self._validate_update_query(parsed_ast)
|
|
78
|
+
elif query_type == 'HYBRID':
|
|
79
|
+
return self._validate_hybrid_query(parsed_ast)
|
|
80
|
+
elif query_type == 'RUN_PIPELINE':
|
|
81
|
+
return self._validate_run_pipeline_query(parsed_ast)
|
|
82
|
+
elif query_type == 'CREATE_RETRIEVAL_PIPELINE':
|
|
83
|
+
return self._validate_run_pipeline_query(parsed_ast) # Use same validation as regular pipelines
|
|
84
|
+
elif query_type == 'CREATE_PIPELINE':
|
|
85
|
+
return self._validate_create_pipeline_query(parsed_ast)
|
|
86
|
+
elif query_type in ['CREATE_NODE', 'UPDATE_NODE', 'DELETE_NODE', 'CREATE_EDGE', 'UPDATE_EDGE', 'DELETE_EDGE', 'SELECT', 'CREATE_GRAPH', 'CREATE_NAMESPACE', 'USE_NAMESPACE', 'SHOW_NAMESPACES', 'MATCH_ENTITY', 'MERGE_NODE']:
|
|
87
|
+
# Basic CRUD operations - no specific validation needed
|
|
88
|
+
return {'valid': True, 'errors': [], 'warnings': []}
|
|
89
|
+
elif query_type in ['TRAVERSE', 'PAGERANK', 'SHORTEST_PATH', 'COMMUNITY_DETECTION', 'CENTRALITY', 'COUNT', 'SHOW', 'HOP', 'HYBRID_SEARCH', 'HYBRID_SEARCH_WITH_WEIGHTS', 'HYBRID_SEARCH_WITH_PROFILE', 'SEARCH_QUERY']:
|
|
90
|
+
# Analytics, traversal, and search queries - no specific validation needed
|
|
91
|
+
return {'valid': True, 'errors': [], 'warnings': []}
|
|
92
|
+
else:
|
|
93
|
+
self._error(f"Unknown query type: {query_type}")
|
|
94
|
+
|
|
95
|
+
except Exception as e:
|
|
96
|
+
self._error(f"Validation failed: {str(e)}")
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
'valid': len(self.validation_errors) == 0,
|
|
100
|
+
'errors': self.validation_errors,
|
|
101
|
+
'warnings': self.validation_warnings
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
def _validate_rag_query(self, ast: Dict[str, Any]) -> Dict[str, Any]:
|
|
105
|
+
"""Validate RAG query semantics"""
|
|
106
|
+
query = ast.get('query', '')
|
|
107
|
+
namespace = ast.get('namespace')
|
|
108
|
+
|
|
109
|
+
# 1. Check namespace exists
|
|
110
|
+
if namespace:
|
|
111
|
+
if not self._namespace_exists(namespace):
|
|
112
|
+
if self.mode == ValidatorMode.AUTO_CREATE:
|
|
113
|
+
self._warn(f"Namespace '{namespace}' will be auto-created")
|
|
114
|
+
else:
|
|
115
|
+
self._error(f"Namespace '{namespace}' does not exist")
|
|
116
|
+
|
|
117
|
+
# 2. Check collection exists (if specified)
|
|
118
|
+
collection = ast.get('collection')
|
|
119
|
+
if collection:
|
|
120
|
+
if not self._collection_exists(namespace, collection):
|
|
121
|
+
if self.mode == ValidatorMode.AUTO_CREATE:
|
|
122
|
+
self._warn(f"Collection '{collection}' will be auto-created")
|
|
123
|
+
else:
|
|
124
|
+
self._error(f"Collection '{collection}' does not exist in namespace '{namespace}'")
|
|
125
|
+
|
|
126
|
+
# 3. Check query is not empty
|
|
127
|
+
if not query or not query.strip():
|
|
128
|
+
self._error("RAG query cannot be empty")
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
'valid': len(self.validation_errors) == 0,
|
|
132
|
+
'errors': self.validation_errors,
|
|
133
|
+
'warnings': self.validation_warnings
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
def _validate_pipeline_query(self, ast: Dict[str, Any]) -> Dict[str, Any]:
|
|
137
|
+
"""Validate CREATE PIPELINE query semantics"""
|
|
138
|
+
pipeline_name = ast.get('pipeline_name', '')
|
|
139
|
+
namespace = ast.get('namespace')
|
|
140
|
+
source_collection = ast.get('source_collection')
|
|
141
|
+
target_collection = ast.get('target_collection')
|
|
142
|
+
stages = ast.get('stages', [])
|
|
143
|
+
|
|
144
|
+
# 1. Check namespace exists
|
|
145
|
+
if namespace:
|
|
146
|
+
if not self._namespace_exists(namespace):
|
|
147
|
+
if self.mode == ValidatorMode.AUTO_CREATE:
|
|
148
|
+
self._warn(f"Namespace '{namespace}' will be auto-created")
|
|
149
|
+
else:
|
|
150
|
+
self._error(f"Namespace '{namespace}' does not exist")
|
|
151
|
+
|
|
152
|
+
# 2. Check source collection exists (if specified)
|
|
153
|
+
if source_collection:
|
|
154
|
+
if not self._collection_exists(namespace, source_collection):
|
|
155
|
+
if self.mode == ValidatorMode.AUTO_CREATE:
|
|
156
|
+
self._warn(f"Source collection '{source_collection}' will be auto-created")
|
|
157
|
+
else:
|
|
158
|
+
self._error(f"Source collection '{source_collection}' does not exist")
|
|
159
|
+
|
|
160
|
+
# 3. Validate each stage
|
|
161
|
+
for stage in stages:
|
|
162
|
+
stage_type = stage.get('type')
|
|
163
|
+
|
|
164
|
+
if stage_type == 'LOAD':
|
|
165
|
+
self._validate_load_stage(stage, namespace, source_collection)
|
|
166
|
+
elif stage_type == 'EXTRACT':
|
|
167
|
+
self._validate_extract_stage(stage)
|
|
168
|
+
elif stage_type == 'CHUNK':
|
|
169
|
+
self._validate_chunk_stage(stage)
|
|
170
|
+
elif stage_type == 'EMBED':
|
|
171
|
+
self._validate_embed_stage(stage)
|
|
172
|
+
elif stage_type == 'INDEX':
|
|
173
|
+
self._validate_index_stage(stage)
|
|
174
|
+
elif stage_type == 'ENTITY_EXTRACT':
|
|
175
|
+
self._validate_entity_stage(stage)
|
|
176
|
+
elif stage_type == 'RELATIONSHIP_EXTRACT':
|
|
177
|
+
self._validate_relationship_stage(stage)
|
|
178
|
+
|
|
179
|
+
# 4. Validate node types
|
|
180
|
+
node_types = ast.get('node_types', [])
|
|
181
|
+
for node_type in node_types:
|
|
182
|
+
if not self._is_valid_node_type(node_type):
|
|
183
|
+
self._warn(f"Unknown node type '{node_type}', will validate at runtime")
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
'valid': len(self.validation_errors) == 0,
|
|
187
|
+
'errors': self.validation_errors,
|
|
188
|
+
'warnings': self.validation_warnings
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
def _validate_retrieve_query(self, ast: Dict[str, Any]) -> Dict[str, Any]:
|
|
192
|
+
"""Validate RETRIEVE query semantics"""
|
|
193
|
+
namespace = ast.get('namespace')
|
|
194
|
+
collection = ast.get('collection')
|
|
195
|
+
strategy = ast.get('strategy')
|
|
196
|
+
profile = ast.get('profile')
|
|
197
|
+
|
|
198
|
+
# 1. Check namespace exists
|
|
199
|
+
if namespace and not self._namespace_exists(namespace):
|
|
200
|
+
self._error(f"Namespace '{namespace}' does not exist")
|
|
201
|
+
|
|
202
|
+
# 2. Check collection exists
|
|
203
|
+
if collection and not self._collection_exists(namespace, collection):
|
|
204
|
+
self._error(f"Collection '{collection}' does not exist")
|
|
205
|
+
|
|
206
|
+
# 3. Validate profile exists
|
|
207
|
+
if profile:
|
|
208
|
+
if not self._profile_exists(profile):
|
|
209
|
+
self._error(f"Profile '{profile}' does not exist")
|
|
210
|
+
|
|
211
|
+
# 4. Validate strategy is supported
|
|
212
|
+
valid_strategies = ['hybrid', 'vector', 'graph', 'combined']
|
|
213
|
+
if strategy and strategy not in valid_strategies:
|
|
214
|
+
self._warn(f"Strategy '{strategy}' is not a standard strategy")
|
|
215
|
+
|
|
216
|
+
return {
|
|
217
|
+
'valid': len(self.validation_errors) == 0,
|
|
218
|
+
'errors': self.validation_errors,
|
|
219
|
+
'warnings': self.validation_warnings
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
def _validate_update_query(self, ast: Dict[str, Any]) -> Dict[str, Any]:
|
|
223
|
+
"""Validate UPDATE query semantics"""
|
|
224
|
+
namespace = ast.get('namespace')
|
|
225
|
+
collection = ast.get('collection')
|
|
226
|
+
|
|
227
|
+
# 1. Check namespace exists
|
|
228
|
+
if namespace and not self._namespace_exists(namespace):
|
|
229
|
+
self._error(f"Namespace '{namespace}' does not exist")
|
|
230
|
+
|
|
231
|
+
# 2. Check collection exists
|
|
232
|
+
if collection and not self._collection_exists(namespace, collection):
|
|
233
|
+
self._error(f"Collection '{collection}' does not exist")
|
|
234
|
+
|
|
235
|
+
# 3. Validate operation type
|
|
236
|
+
operation = ast.get('operation', '')
|
|
237
|
+
valid_operations = ['insert', 'update', 'delete', 'upsert']
|
|
238
|
+
if operation and operation not in valid_operations:
|
|
239
|
+
self._error(f"Invalid operation type '{operation}'")
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
'valid': len(self.validation_errors) == 0,
|
|
243
|
+
'errors': self.validation_errors,
|
|
244
|
+
'warnings': self.validation_warnings
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
def _validate_hybrid_query(self, ast: Dict[str, Any]) -> Dict[str, Any]:
|
|
248
|
+
"""Validate HYBRID search query semantics"""
|
|
249
|
+
namespace = ast.get('namespace')
|
|
250
|
+
collection = ast.get('collection')
|
|
251
|
+
|
|
252
|
+
# Validate using RAG + RETRIEVE validators
|
|
253
|
+
rag_result = self._validate_rag_query(ast)
|
|
254
|
+
retrieve_result = self._validate_retrieve_query(ast)
|
|
255
|
+
|
|
256
|
+
return {
|
|
257
|
+
'valid': rag_result['valid'] and retrieve_result['valid'],
|
|
258
|
+
'errors': rag_result.get('errors', []) + retrieve_result.get('errors', []),
|
|
259
|
+
'warnings': rag_result.get('warnings', []) + retrieve_result.get('warnings', [])
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
def _validate_create_pipeline_query(self, ast: Dict[str, Any]) -> Dict[str, Any]:
|
|
263
|
+
"""Validate CREATE PIPELINE query."""
|
|
264
|
+
pipeline_name = ast.get('pipeline_name', '')
|
|
265
|
+
namespace = ast.get('namespace', '')
|
|
266
|
+
|
|
267
|
+
if not pipeline_name:
|
|
268
|
+
self._error("Pipeline name is required")
|
|
269
|
+
|
|
270
|
+
if not namespace:
|
|
271
|
+
self._error("Namespace is required")
|
|
272
|
+
|
|
273
|
+
return {
|
|
274
|
+
'valid': len(self.validation_errors) == 0,
|
|
275
|
+
'errors': self.validation_errors,
|
|
276
|
+
'warnings': self.validation_warnings
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
def _validate_run_pipeline_query(self, ast: Dict[str, Any]) -> Dict[str, Any]:
|
|
280
|
+
"""Validate RUN PIPELINE query semantics"""
|
|
281
|
+
# Extract pipeline name from AST
|
|
282
|
+
pipeline_name = ast.get('pipeline_name')
|
|
283
|
+
|
|
284
|
+
if not pipeline_name:
|
|
285
|
+
# Don't error if pipeline_name is not found - it might be in AST nodes
|
|
286
|
+
self._warn("Pipeline name not found in AST top level")
|
|
287
|
+
|
|
288
|
+
# Validate that the pipeline exists (could be expanded)
|
|
289
|
+
if pipeline_name and len(pipeline_name) < 3:
|
|
290
|
+
self._warn(f"Pipeline name '{pipeline_name}' seems too short")
|
|
291
|
+
|
|
292
|
+
return {
|
|
293
|
+
'valid': len(self.validation_errors) == 0,
|
|
294
|
+
'errors': self.validation_errors,
|
|
295
|
+
'warnings': self.validation_warnings
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
def _validate_load_stage(self, stage: Dict[str, Any], namespace: str, collection: str):
|
|
299
|
+
"""Validate LOAD stage semantics"""
|
|
300
|
+
file_path = stage.get('file_path', '')
|
|
301
|
+
|
|
302
|
+
# Check file exists (basic validation)
|
|
303
|
+
if file_path and not file_path.startswith(('http://', 'https://', '/')):
|
|
304
|
+
# Local file validation
|
|
305
|
+
import os
|
|
306
|
+
if not os.path.exists(file_path):
|
|
307
|
+
self._warn(f"File '{file_path}' may not exist (will check at runtime)")
|
|
308
|
+
|
|
309
|
+
def _validate_extract_stage(self, stage: Dict[str, Any]):
|
|
310
|
+
"""Validate EXTRACT stage semantics"""
|
|
311
|
+
# Validate extract modes
|
|
312
|
+
modes = stage.get('modes', [])
|
|
313
|
+
valid_modes = ['text', 'table', 'image', 'audio', 'video']
|
|
314
|
+
for mode in modes:
|
|
315
|
+
if mode not in valid_modes:
|
|
316
|
+
self._warn(f"Extract mode '{mode}' may not be supported")
|
|
317
|
+
|
|
318
|
+
def _validate_chunk_stage(self, stage: Dict[str, Any]):
|
|
319
|
+
"""Validate CHUNK stage semantics"""
|
|
320
|
+
max_tokens = stage.get('max_tokens', 0)
|
|
321
|
+
if max_tokens <= 0:
|
|
322
|
+
self._warn("max_tokens should be greater than 0")
|
|
323
|
+
|
|
324
|
+
def _validate_embed_stage(self, stage: Dict[str, Any]):
|
|
325
|
+
"""Validate EMBED stage semantics"""
|
|
326
|
+
model = stage.get('model', '')
|
|
327
|
+
if not model:
|
|
328
|
+
self._error("Embedding model is required")
|
|
329
|
+
|
|
330
|
+
def _validate_index_stage(self, stage: Dict[str, Any]):
|
|
331
|
+
"""Validate INDEX stage semantics"""
|
|
332
|
+
index_types = stage.get('index_types', [])
|
|
333
|
+
valid_types = ['bm25', 'vector', 'graph', 'hybrid']
|
|
334
|
+
for idx_type in index_types:
|
|
335
|
+
if idx_type not in valid_types:
|
|
336
|
+
self._warn(f"Index type '{idx_type}' may not be supported")
|
|
337
|
+
|
|
338
|
+
def _validate_entity_stage(self, stage: Dict[str, Any]):
|
|
339
|
+
"""Validate ENTITY EXTRACT stage semantics"""
|
|
340
|
+
llm_model = stage.get('llm_model', '')
|
|
341
|
+
if not llm_model:
|
|
342
|
+
self._error("LLM model is required for entity extraction")
|
|
343
|
+
|
|
344
|
+
def _validate_relationship_stage(self, stage: Dict[str, Any]):
|
|
345
|
+
"""Validate RELATIONSHIP EXTRACT stage semantics"""
|
|
346
|
+
llm_model = stage.get('llm_model', '')
|
|
347
|
+
if not llm_model:
|
|
348
|
+
self._error("LLM model is required for relationship extraction")
|
|
349
|
+
|
|
350
|
+
def _namespace_exists(self, namespace: str) -> bool:
|
|
351
|
+
"""Check if namespace exists"""
|
|
352
|
+
if not self.db_interface:
|
|
353
|
+
return True # Skip validation if no DB interface
|
|
354
|
+
return self.db_interface.namespace_exists(namespace)
|
|
355
|
+
|
|
356
|
+
def _collection_exists(self, namespace: str, collection: str) -> bool:
|
|
357
|
+
"""Check if collection exists in namespace"""
|
|
358
|
+
if not self.db_interface:
|
|
359
|
+
return True # Skip validation if no DB interface
|
|
360
|
+
return self.db_interface.collection_exists(namespace, collection)
|
|
361
|
+
|
|
362
|
+
def _profile_exists(self, profile: str) -> bool:
|
|
363
|
+
"""Check if profile exists"""
|
|
364
|
+
if not self.db_interface:
|
|
365
|
+
return True # Skip validation if no DB interface
|
|
366
|
+
return self.db_interface.profile_exists(profile)
|
|
367
|
+
|
|
368
|
+
def _is_valid_node_type(self, node_type: str) -> bool:
|
|
369
|
+
"""Check if node type is valid"""
|
|
370
|
+
try:
|
|
371
|
+
return NodeType(node_type) is not None
|
|
372
|
+
except ValueError:
|
|
373
|
+
return False
|
|
374
|
+
|
|
375
|
+
def _error(self, message: str):
|
|
376
|
+
"""Add validation error"""
|
|
377
|
+
self.validation_errors.append(message)
|
|
378
|
+
if self.mode == ValidatorMode.STRICT:
|
|
379
|
+
raise ValidationError(message)
|
|
380
|
+
|
|
381
|
+
def _warn(self, message: str):
|
|
382
|
+
"""Add validation warning"""
|
|
383
|
+
self.validation_warnings.append(message)
|
|
384
|
+
|
|
385
|
+
def get_dependencies(self, ast: Dict[str, Any]) -> List[str]:
|
|
386
|
+
"""
|
|
387
|
+
Get list of dependencies for this query
|
|
388
|
+
(e.g., namespaces, collections, tables, columns)
|
|
389
|
+
"""
|
|
390
|
+
dependencies = []
|
|
391
|
+
|
|
392
|
+
namespace = ast.get('namespace')
|
|
393
|
+
if namespace:
|
|
394
|
+
dependencies.append(f"namespace:{namespace}")
|
|
395
|
+
|
|
396
|
+
collection = ast.get('collection')
|
|
397
|
+
if collection:
|
|
398
|
+
dependencies.append(f"collection:{namespace}:{collection}")
|
|
399
|
+
|
|
400
|
+
# Add more dependencies as needed
|
|
401
|
+
# e.g., tables, columns, profiles, etc.
|
|
402
|
+
|
|
403
|
+
return dependencies
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
# Validator factory for different modes
|
|
407
|
+
def create_validator(mode: str = "strict", db_interface=None) -> AIQLValidator:
|
|
408
|
+
"""
|
|
409
|
+
Create validator with specified mode
|
|
410
|
+
|
|
411
|
+
Args:
|
|
412
|
+
mode: 'strict', 'permissive', or 'auto_create'
|
|
413
|
+
db_interface: Optional DB interface for resource checking
|
|
414
|
+
|
|
415
|
+
Returns:
|
|
416
|
+
Configured AIQLValidator instance
|
|
417
|
+
"""
|
|
418
|
+
validator_mode = ValidatorMode(mode)
|
|
419
|
+
return AIQLValidator(db_interface=db_interface, mode=validator_mode)
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
# Example usage:
|
|
423
|
+
# validator = create_validator(mode="strict", db_interface=db)
|
|
424
|
+
# result = validator.validate(parsed_ast)
|
|
425
|
+
|