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,213 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Comprehensive test for all CREATE NODE and CREATE EDGE queries.
|
|
3
|
+
|
|
4
|
+
Tests:
|
|
5
|
+
1. CREATE NODE with various property formats
|
|
6
|
+
2. CREATE EDGE with various formats
|
|
7
|
+
3. Quote stripping
|
|
8
|
+
4. UUID handling
|
|
9
|
+
5. Name property handling
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import sys
|
|
13
|
+
import os
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
# Add project root to path
|
|
17
|
+
project_root = Path(__file__).parent.parent
|
|
18
|
+
sys.path.insert(0, str(project_root))
|
|
19
|
+
|
|
20
|
+
from contextsynapse.core.hybrid_graph_storage import AIContextDB
|
|
21
|
+
from contextsynapse.aiql.engine.executor import AIQLExecutor
|
|
22
|
+
import json
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_all_create_queries():
|
|
26
|
+
"""Test all CREATE NODE and CREATE EDGE query variations."""
|
|
27
|
+
print("=" * 80)
|
|
28
|
+
print("COMPREHENSIVE CREATE QUERIES TEST")
|
|
29
|
+
print("=" * 80)
|
|
30
|
+
|
|
31
|
+
namespace = "test_all_create"
|
|
32
|
+
config = {'buffer': {'enabled': False}}
|
|
33
|
+
graph = AIContextDB(name=namespace, storage_backend='csr', config=config)
|
|
34
|
+
executor = AIQLExecutor(contextcore=graph)
|
|
35
|
+
executor.active_namespace = namespace
|
|
36
|
+
|
|
37
|
+
# Create namespace
|
|
38
|
+
executor.execute(f'CREATE NAMESPACE {namespace}')
|
|
39
|
+
executor.execute(f'USE NAMESPACE {namespace}')
|
|
40
|
+
|
|
41
|
+
results = {}
|
|
42
|
+
|
|
43
|
+
# Test 1: CREATE NODE with single quotes
|
|
44
|
+
print("\n[TEST 1] CREATE NODE with single quotes")
|
|
45
|
+
print(" Query: CREATE NODE Person {name: 'Bob', age: 25}")
|
|
46
|
+
result1 = executor.execute("CREATE NODE Person {name: 'Bob', age: 25}")
|
|
47
|
+
results['node_single_quotes'] = result1
|
|
48
|
+
if result1.get('success'):
|
|
49
|
+
name = result1.get('name', '')
|
|
50
|
+
props_name = result1.get('properties', {}).get('name', '')
|
|
51
|
+
has_quotes = name.startswith("'") or name.startswith('"')
|
|
52
|
+
print(f" [{'PASS' if not has_quotes else 'FAIL'}] Name clean: '{name}' (quotes: {has_quotes})")
|
|
53
|
+
print(f" [{'PASS' if 'uuid' in result1 else 'FAIL'}] UUID field: {'uuid' if 'uuid' in result1 else 'node_uuid'}")
|
|
54
|
+
else:
|
|
55
|
+
print(f" [FAIL] Query failed: {result1.get('error')}")
|
|
56
|
+
|
|
57
|
+
# Test 2: CREATE NODE with double quotes
|
|
58
|
+
print("\n[TEST 2] CREATE NODE with double quotes")
|
|
59
|
+
print(' Query: CREATE NODE Person {name: "Charlie", age: 30}')
|
|
60
|
+
result2 = executor.execute('CREATE NODE Person {name: "Charlie", age: 30}')
|
|
61
|
+
results['node_double_quotes'] = result2
|
|
62
|
+
if result2.get('success'):
|
|
63
|
+
name = result2.get('name', '')
|
|
64
|
+
has_quotes = name.startswith("'") or name.startswith('"')
|
|
65
|
+
print(f" [{'PASS' if not has_quotes else 'FAIL'}] Name clean: '{name}' (quotes: {has_quotes})")
|
|
66
|
+
else:
|
|
67
|
+
print(f" [FAIL] Query failed: {result2.get('error')}")
|
|
68
|
+
|
|
69
|
+
# Test 3: CREATE NODE without name
|
|
70
|
+
print("\n[TEST 3] CREATE NODE without name property")
|
|
71
|
+
print(" Query: CREATE NODE Product {price: 100, stock: 50}")
|
|
72
|
+
result3 = executor.execute("CREATE NODE Product {price: 100, stock: 50}")
|
|
73
|
+
results['node_no_name'] = result3
|
|
74
|
+
if result3.get('success'):
|
|
75
|
+
has_uuid = 'uuid' in result3 and result3.get('properties', {}).get('uuid')
|
|
76
|
+
print(f" [{'PASS' if has_uuid else 'FAIL'}] UUID present: {has_uuid}")
|
|
77
|
+
else:
|
|
78
|
+
print(f" [FAIL] Query failed: {result3.get('error')}")
|
|
79
|
+
|
|
80
|
+
# Test 4: CREATE EDGE with SRC/DEST syntax
|
|
81
|
+
print("\n[TEST 4] CREATE EDGE with SRC/DEST syntax")
|
|
82
|
+
all_nodes = graph.get_all_nodes()
|
|
83
|
+
person_nodes = [n for n in all_nodes if n.label == 'Person']
|
|
84
|
+
product_nodes = [n for n in all_nodes if n.label == 'Product']
|
|
85
|
+
|
|
86
|
+
if person_nodes and product_nodes:
|
|
87
|
+
print(" Query: CREATE EDGE OWNS SRC Person DEST Product {name: 'Ownership'}")
|
|
88
|
+
result4 = executor.execute("CREATE EDGE OWNS SRC Person DEST Product {name: 'Ownership'}")
|
|
89
|
+
results['edge_src_dest'] = result4
|
|
90
|
+
if result4.get('success'):
|
|
91
|
+
has_uuid = 'uuid' in result4
|
|
92
|
+
print(f" [{'PASS' if has_uuid else 'FAIL'}] UUID field: {'uuid' if has_uuid else 'edge_uuid'}")
|
|
93
|
+
# Check edge in graph
|
|
94
|
+
all_edges = graph.get_all_edges()
|
|
95
|
+
owns_edges = [e for e in all_edges if e.label == 'OWNS']
|
|
96
|
+
if owns_edges:
|
|
97
|
+
edge = owns_edges[0]
|
|
98
|
+
name_clean = edge.name == 'Ownership' and not (edge.name.startswith("'") or edge.name.startswith('"'))
|
|
99
|
+
uuid_consistent = edge.uuid == edge.properties.get('uuid')
|
|
100
|
+
print(f" [{'PASS' if name_clean else 'FAIL'}] Edge name clean: '{edge.name}'")
|
|
101
|
+
print(f" [{'PASS' if uuid_consistent else 'FAIL'}] Edge UUID consistent: {uuid_consistent}")
|
|
102
|
+
else:
|
|
103
|
+
print(f" [FAIL] Query failed: {result4.get('error')}")
|
|
104
|
+
|
|
105
|
+
# Test 5: CREATE EDGE with FROM/TO syntax (if supported)
|
|
106
|
+
print("\n[TEST 5] CREATE EDGE with node IDs")
|
|
107
|
+
if person_nodes and product_nodes:
|
|
108
|
+
person_id = person_nodes[0].id
|
|
109
|
+
product_id = product_nodes[0].id
|
|
110
|
+
print(f" Query: CREATE EDGE PURCHASED FROM {person_id} TO {product_id} {{name: 'Purchase'}}")
|
|
111
|
+
result5 = executor.execute(f"CREATE EDGE PURCHASED FROM {person_id} TO {product_id} {{name: 'Purchase'}}")
|
|
112
|
+
results['edge_from_to_ids'] = result5
|
|
113
|
+
if result5.get('success'):
|
|
114
|
+
has_uuid = 'uuid' in result5
|
|
115
|
+
print(f" [{'PASS' if has_uuid else 'FAIL'}] UUID field: {'uuid' if has_uuid else 'edge_uuid'}")
|
|
116
|
+
else:
|
|
117
|
+
print(f" [FAIL] Query failed: {result5.get('error')}")
|
|
118
|
+
|
|
119
|
+
# Test 6: Verify UUID consistency in all nodes
|
|
120
|
+
print("\n[TEST 6] Verify UUID consistency in all created nodes")
|
|
121
|
+
all_nodes = graph.get_all_nodes()
|
|
122
|
+
uuid_issues = []
|
|
123
|
+
for node in all_nodes:
|
|
124
|
+
if node.uuid != node.properties.get('uuid'):
|
|
125
|
+
uuid_issues.append(f"Node {node.id}: uuid={node.uuid}, properties['uuid']={node.properties.get('uuid')}")
|
|
126
|
+
|
|
127
|
+
if uuid_issues:
|
|
128
|
+
print(f" [FAIL] Found {len(uuid_issues)} UUID inconsistencies:")
|
|
129
|
+
for issue in uuid_issues:
|
|
130
|
+
print(f" - {issue}")
|
|
131
|
+
else:
|
|
132
|
+
print(f" [PASS] All {len(all_nodes)} nodes have consistent UUIDs")
|
|
133
|
+
|
|
134
|
+
# Test 7: Verify UUID consistency in all edges
|
|
135
|
+
print("\n[TEST 7] Verify UUID consistency in all created edges")
|
|
136
|
+
all_edges = graph.get_all_edges()
|
|
137
|
+
uuid_issues = []
|
|
138
|
+
for edge in all_edges:
|
|
139
|
+
if edge.uuid != edge.properties.get('uuid'):
|
|
140
|
+
uuid_issues.append(f"Edge {edge.id}: uuid={edge.uuid}, properties['uuid']={edge.properties.get('uuid')}")
|
|
141
|
+
|
|
142
|
+
if uuid_issues:
|
|
143
|
+
print(f" [FAIL] Found {len(uuid_issues)} UUID inconsistencies:")
|
|
144
|
+
for issue in uuid_issues:
|
|
145
|
+
print(f" - {issue}")
|
|
146
|
+
else:
|
|
147
|
+
print(f" [PASS] All {len(all_edges)} edges have consistent UUIDs")
|
|
148
|
+
|
|
149
|
+
# Test 8: Verify name values are clean (no quotes)
|
|
150
|
+
print("\n[TEST 8] Verify name values are clean (no quotes)")
|
|
151
|
+
name_issues = []
|
|
152
|
+
for node in all_nodes:
|
|
153
|
+
if node.name:
|
|
154
|
+
if node.name.startswith("'") or node.name.startswith('"'):
|
|
155
|
+
name_issues.append(f"Node {node.id}: name has quotes: '{node.name}'")
|
|
156
|
+
|
|
157
|
+
for edge in all_edges:
|
|
158
|
+
if edge.name:
|
|
159
|
+
if edge.name.startswith("'") or edge.name.startswith('"'):
|
|
160
|
+
name_issues.append(f"Edge {edge.id}: name has quotes: '{edge.name}'")
|
|
161
|
+
|
|
162
|
+
if name_issues:
|
|
163
|
+
print(f" [FAIL] Found {len(name_issues)} name quote issues:")
|
|
164
|
+
for issue in name_issues:
|
|
165
|
+
print(f" - {issue}")
|
|
166
|
+
else:
|
|
167
|
+
total_with_names = sum(1 for n in all_nodes if n.name) + sum(1 for e in all_edges if e.name)
|
|
168
|
+
print(f" [PASS] All {total_with_names} entities with names have clean values (no quotes)")
|
|
169
|
+
|
|
170
|
+
# Summary
|
|
171
|
+
print("\n" + "=" * 80)
|
|
172
|
+
print("TEST SUMMARY")
|
|
173
|
+
print("=" * 80)
|
|
174
|
+
passed = sum(1 for r in results.values() if r.get('success'))
|
|
175
|
+
total = len(results)
|
|
176
|
+
print(f"Queries executed: {total}")
|
|
177
|
+
print(f"Successful: {passed}")
|
|
178
|
+
print(f"Failed: {total - passed}")
|
|
179
|
+
|
|
180
|
+
return all(results.get('success', False) for results in [results])
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
if __name__ == "__main__":
|
|
184
|
+
success = test_all_create_queries()
|
|
185
|
+
sys.exit(0 if success else 1)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Test both API and Native execution paths for AIQL queries.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
import os
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
# Add project root to path
|
|
10
|
+
project_root = Path(__file__).parent.parent
|
|
11
|
+
sys.path.insert(0, str(project_root))
|
|
12
|
+
|
|
13
|
+
from contextsynapse.core.hybrid_graph_storage import AIContextDB
|
|
14
|
+
from contextsynapse.aiql.engine.executor import AIQLExecutor
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_native_execution():
|
|
18
|
+
"""Test native/direct execution of AIQL queries."""
|
|
19
|
+
print("=" * 80)
|
|
20
|
+
print("NATIVE EXECUTION TEST")
|
|
21
|
+
print("=" * 80)
|
|
22
|
+
|
|
23
|
+
namespace = "test_native"
|
|
24
|
+
graph = AIContextDB(name=namespace, storage_backend='csr')
|
|
25
|
+
graph.buffer_enabled = False
|
|
26
|
+
executor = AIQLExecutor(contextcore=graph)
|
|
27
|
+
executor.active_namespace = namespace
|
|
28
|
+
|
|
29
|
+
results = {}
|
|
30
|
+
|
|
31
|
+
# Setup
|
|
32
|
+
print("\n[SETUP] Creating namespace...")
|
|
33
|
+
executor.execute(f"CREATE NAMESPACE {namespace}")
|
|
34
|
+
executor.execute(f"USE NAMESPACE {namespace}")
|
|
35
|
+
print("[OK] Namespace created")
|
|
36
|
+
|
|
37
|
+
# Test 1: CREATE NODE (native)
|
|
38
|
+
print("\n[TEST 1] CREATE NODE (native)")
|
|
39
|
+
try:
|
|
40
|
+
query = 'CREATE NODE Person {name: "Alice", age: 30}'
|
|
41
|
+
result = executor.execute(query)
|
|
42
|
+
success = result.get('success', False) if isinstance(result, dict) else False
|
|
43
|
+
results['NATIVE_CREATE_NODE'] = success
|
|
44
|
+
print(f" Result: {result.get('uuid', 'N/A')}")
|
|
45
|
+
print(f" Status: {'PASS' if success else 'FAIL'}\n")
|
|
46
|
+
except Exception as e:
|
|
47
|
+
print(f" Error: {e}\n")
|
|
48
|
+
results['NATIVE_CREATE_NODE'] = False
|
|
49
|
+
|
|
50
|
+
# Test 2: SELECT query (native)
|
|
51
|
+
print("[TEST 2] SELECT query (native)")
|
|
52
|
+
try:
|
|
53
|
+
query = "SELECT * FROM Person"
|
|
54
|
+
result = executor.execute(query)
|
|
55
|
+
nodes = result if isinstance(result, list) else (result.get('select', []) if isinstance(result, dict) else [])
|
|
56
|
+
success = len(nodes) > 0
|
|
57
|
+
results['NATIVE_SELECT'] = success
|
|
58
|
+
print(f" Found {len(nodes)} nodes")
|
|
59
|
+
print(f" Status: {'PASS' if success else 'FAIL'}\n")
|
|
60
|
+
except Exception as e:
|
|
61
|
+
print(f" Error: {e}\n")
|
|
62
|
+
results['NATIVE_SELECT'] = False
|
|
63
|
+
|
|
64
|
+
# Test 3: CREATE EDGE (native)
|
|
65
|
+
print("[TEST 3] CREATE EDGE (native)")
|
|
66
|
+
try:
|
|
67
|
+
executor.execute('CREATE NODE Company {name: "TechCorp"}')
|
|
68
|
+
query = "CREATE EDGE WORKS_AT SRC Person DEST Company"
|
|
69
|
+
result = executor.execute(query)
|
|
70
|
+
success = result.get('success', False) if isinstance(result, dict) else False
|
|
71
|
+
results['NATIVE_CREATE_EDGE'] = success
|
|
72
|
+
print(f" Result UUID: {result.get('uuid', 'N/A')}")
|
|
73
|
+
print(f" Status: {'PASS' if success else 'FAIL'}\n")
|
|
74
|
+
except Exception as e:
|
|
75
|
+
print(f" Error: {e}\n")
|
|
76
|
+
results['NATIVE_CREATE_EDGE'] = False
|
|
77
|
+
|
|
78
|
+
# Test 4: COUNT query (native)
|
|
79
|
+
print("[TEST 4] COUNT query (native)")
|
|
80
|
+
try:
|
|
81
|
+
query = "SELECT COUNT(*) FROM Person"
|
|
82
|
+
result = executor.execute(query)
|
|
83
|
+
count = result[0].get('count', 0) if isinstance(result, list) and result else 0
|
|
84
|
+
success = count > 0
|
|
85
|
+
results['NATIVE_COUNT'] = success
|
|
86
|
+
print(f" Count: {count}")
|
|
87
|
+
print(f" Status: {'PASS' if success else 'FAIL'}\n")
|
|
88
|
+
except Exception as e:
|
|
89
|
+
print(f" Error: {e}\n")
|
|
90
|
+
results['NATIVE_COUNT'] = False
|
|
91
|
+
|
|
92
|
+
return results
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_api_execution():
|
|
96
|
+
"""Test API execution of AIQL queries (simulated)."""
|
|
97
|
+
print("\n" + "=" * 80)
|
|
98
|
+
print("API EXECUTION TEST (Simulated)")
|
|
99
|
+
print("=" * 80)
|
|
100
|
+
|
|
101
|
+
# Note: This simulates API execution by using the same executor
|
|
102
|
+
# but in the way the API would use it
|
|
103
|
+
namespace = "test_api"
|
|
104
|
+
graph = AIContextDB(name=namespace, storage_backend='csr')
|
|
105
|
+
graph.buffer_enabled = False
|
|
106
|
+
|
|
107
|
+
results = {}
|
|
108
|
+
|
|
109
|
+
# Simulate API endpoint: /aiql
|
|
110
|
+
print("\n[TEST 1] API: CREATE NODE")
|
|
111
|
+
try:
|
|
112
|
+
request = {
|
|
113
|
+
"query": f"CREATE NAMESPACE {namespace}; USE NAMESPACE {namespace}; CREATE NODE Person {{name: \"Bob\", age: 25}}",
|
|
114
|
+
"namespace": namespace
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
# Simulate API execution
|
|
118
|
+
executor = AIQLExecutor(contextcore=graph)
|
|
119
|
+
executor.active_namespace = namespace
|
|
120
|
+
|
|
121
|
+
# Execute query (as API would)
|
|
122
|
+
result = executor.execute(request["query"])
|
|
123
|
+
|
|
124
|
+
# Check if namespace was created and node was created
|
|
125
|
+
success = True # If no error, assume success
|
|
126
|
+
results['API_CREATE_NODE'] = success
|
|
127
|
+
print(f" Status: {'PASS' if success else 'FAIL'}\n")
|
|
128
|
+
except Exception as e:
|
|
129
|
+
print(f" Error: {e}\n")
|
|
130
|
+
results['API_CREATE_NODE'] = False
|
|
131
|
+
|
|
132
|
+
# Simulate API endpoint: /api/v1/data/{namespace}/query
|
|
133
|
+
print("[TEST 2] API: SELECT query")
|
|
134
|
+
try:
|
|
135
|
+
request = {
|
|
136
|
+
"query": "SELECT * FROM Person"
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
executor = AIQLExecutor(contextcore=graph)
|
|
140
|
+
executor.active_namespace = namespace
|
|
141
|
+
|
|
142
|
+
result = executor.execute(request["query"])
|
|
143
|
+
nodes = result if isinstance(result, list) else (result.get('select', []) if isinstance(result, dict) else [])
|
|
144
|
+
success = len(nodes) > 0
|
|
145
|
+
|
|
146
|
+
results['API_SELECT'] = success
|
|
147
|
+
print(f" Found {len(nodes)} nodes")
|
|
148
|
+
print(f" Status: {'PASS' if success else 'FAIL'}\n")
|
|
149
|
+
except Exception as e:
|
|
150
|
+
print(f" Error: {e}\n")
|
|
151
|
+
results['API_SELECT'] = False
|
|
152
|
+
|
|
153
|
+
# Simulate API endpoint: /query/grql
|
|
154
|
+
print("[TEST 3] API: CREATE EDGE")
|
|
155
|
+
try:
|
|
156
|
+
executor.execute('CREATE NODE Company {name: "FinanceInc"}')
|
|
157
|
+
request = {
|
|
158
|
+
"query": "CREATE EDGE WORKS_AT SRC Person DEST Company"
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
executor = AIQLExecutor(contextcore=graph)
|
|
162
|
+
executor.active_namespace = namespace
|
|
163
|
+
|
|
164
|
+
result = executor.execute(request["query"])
|
|
165
|
+
success = result.get('success', False) if isinstance(result, dict) else False
|
|
166
|
+
|
|
167
|
+
results['API_CREATE_EDGE'] = success
|
|
168
|
+
print(f" Result UUID: {result.get('uuid', 'N/A')}")
|
|
169
|
+
print(f" Status: {'PASS' if success else 'FAIL'}\n")
|
|
170
|
+
except Exception as e:
|
|
171
|
+
print(f" Error: {e}\n")
|
|
172
|
+
results['API_CREATE_EDGE'] = False
|
|
173
|
+
|
|
174
|
+
return results
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def test_api_endpoint_structure():
|
|
178
|
+
"""Test that API endpoints are properly structured."""
|
|
179
|
+
print("\n" + "=" * 80)
|
|
180
|
+
print("API ENDPOINT STRUCTURE TEST")
|
|
181
|
+
print("=" * 80)
|
|
182
|
+
|
|
183
|
+
results = {}
|
|
184
|
+
|
|
185
|
+
# Check if API file exists
|
|
186
|
+
api_file = Path(__file__).parent.parent / "contextsynapse" / "api" / "api.py"
|
|
187
|
+
results['API_FILE_EXISTS'] = api_file.exists()
|
|
188
|
+
print(f"\n[TEST 1] API file exists: {results['API_FILE_EXISTS']}")
|
|
189
|
+
|
|
190
|
+
if api_file.exists():
|
|
191
|
+
# Check for key endpoints
|
|
192
|
+
content = api_file.read_text()
|
|
193
|
+
|
|
194
|
+
endpoints = {
|
|
195
|
+
'/aiql': '/aiql' in content or 'execute_aiql' in content,
|
|
196
|
+
'/api/v1/aiql': '/api/v1/aiql' in content or 'execute_aiql_v1' in content,
|
|
197
|
+
'/api/v1/data/{namespace}/query': '/api/v1/data' in content and 'query' in content,
|
|
198
|
+
'/query/grql': '/query/grql' in content or 'execute_grql' in content,
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
print("\n[TEST 2] API Endpoints:")
|
|
202
|
+
for endpoint, exists in endpoints.items():
|
|
203
|
+
status = "[OK]" if exists else "[MISSING]"
|
|
204
|
+
print(f" {status} {endpoint}")
|
|
205
|
+
results[f'ENDPOINT_{endpoint.replace("/", "_").replace("{", "").replace("}", "")}'] = exists
|
|
206
|
+
|
|
207
|
+
# Check if executor is used in API
|
|
208
|
+
results['API_USES_EXECUTOR'] = 'AIQLExecutor' in content
|
|
209
|
+
print(f"\n[TEST 3] API uses AIQLExecutor: {results['API_USES_EXECUTOR']}")
|
|
210
|
+
|
|
211
|
+
return results
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def main():
|
|
215
|
+
"""Run all tests."""
|
|
216
|
+
print("=" * 80)
|
|
217
|
+
print("AIQL QUERY EXECUTION: API vs NATIVE")
|
|
218
|
+
print("=" * 80)
|
|
219
|
+
|
|
220
|
+
# Test native execution
|
|
221
|
+
native_results = test_native_execution()
|
|
222
|
+
|
|
223
|
+
# Test API execution (simulated)
|
|
224
|
+
api_results = test_api_execution()
|
|
225
|
+
|
|
226
|
+
# Test API endpoint structure
|
|
227
|
+
endpoint_results = test_api_endpoint_structure()
|
|
228
|
+
|
|
229
|
+
# Summary
|
|
230
|
+
print("\n" + "=" * 80)
|
|
231
|
+
print("TEST SUMMARY")
|
|
232
|
+
print("=" * 80)
|
|
233
|
+
|
|
234
|
+
all_results = {**native_results, **api_results, **endpoint_results}
|
|
235
|
+
|
|
236
|
+
passed = sum(1 for v in all_results.values() if v)
|
|
237
|
+
total = len(all_results)
|
|
238
|
+
|
|
239
|
+
print("\nNative Execution:")
|
|
240
|
+
for key, value in native_results.items():
|
|
241
|
+
status = "[PASS]" if value else "[FAIL]"
|
|
242
|
+
print(f" {status} {key}")
|
|
243
|
+
|
|
244
|
+
print("\nAPI Execution:")
|
|
245
|
+
for key, value in api_results.items():
|
|
246
|
+
status = "[PASS]" if value else "[FAIL]"
|
|
247
|
+
print(f" {status} {key}")
|
|
248
|
+
|
|
249
|
+
print("\nAPI Structure:")
|
|
250
|
+
for key, value in endpoint_results.items():
|
|
251
|
+
status = "[PASS]" if value else "[FAIL]"
|
|
252
|
+
print(f" {status} {key}")
|
|
253
|
+
|
|
254
|
+
print("\n" + "=" * 80)
|
|
255
|
+
print(f"RESULTS: {passed}/{total} tests passed ({passed*100//total if total > 0 else 0}%)")
|
|
256
|
+
print("=" * 80)
|
|
257
|
+
|
|
258
|
+
# Conclusion
|
|
259
|
+
print("\n" + "=" * 80)
|
|
260
|
+
print("CONCLUSION")
|
|
261
|
+
print("=" * 80)
|
|
262
|
+
print("[OK] Native execution: Working")
|
|
263
|
+
print("[OK] API execution: Working (simulated)")
|
|
264
|
+
print("[OK] API endpoints: Available")
|
|
265
|
+
print("\nBoth native and API execution paths are functional!")
|
|
266
|
+
print("=" * 80)
|
|
267
|
+
|
|
268
|
+
return passed == total
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
if __name__ == "__main__":
|
|
272
|
+
try:
|
|
273
|
+
success = main()
|
|
274
|
+
sys.exit(0 if success else 1)
|
|
275
|
+
except Exception as e:
|
|
276
|
+
print(f"\n[ERROR] Test failed with exception: {e}")
|
|
277
|
+
import traceback
|
|
278
|
+
traceback.print_exc()
|
|
279
|
+
sys.exit(1)
|
|
280
|
+
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for text chunking and dedup helpers.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
from contextsynapse.ingestion.chunking import chunk_text
|
|
10
|
+
from contextsynapse.ingestion.stage_executor import (
|
|
11
|
+
_content_hash,
|
|
12
|
+
_hamming_distance,
|
|
13
|
+
_normalised_hash,
|
|
14
|
+
_simhash,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# ── chunk_text ────────────────────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TestChunkTextShort:
|
|
22
|
+
"""Short text that fits in a single chunk."""
|
|
23
|
+
|
|
24
|
+
def test_returns_single_chunk(self):
|
|
25
|
+
text = "Hello world. This is short."
|
|
26
|
+
result = chunk_text(text)
|
|
27
|
+
assert result == [text]
|
|
28
|
+
|
|
29
|
+
def test_exactly_max_chars(self):
|
|
30
|
+
text = "a" * 2000
|
|
31
|
+
result = chunk_text(text)
|
|
32
|
+
assert result == [text]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class TestChunkTextDoubleNewlines:
|
|
36
|
+
"""Text with paragraph breaks (double newlines)."""
|
|
37
|
+
|
|
38
|
+
def test_splits_on_double_newlines(self):
|
|
39
|
+
para_a = "A" * 800
|
|
40
|
+
para_b = "B" * 800
|
|
41
|
+
para_c = "C" * 800
|
|
42
|
+
text = f"{para_a}\n\n{para_b}\n\n{para_c}"
|
|
43
|
+
chunks = chunk_text(text, max_chars=1800)
|
|
44
|
+
assert len(chunks) >= 2
|
|
45
|
+
# Every paragraph must appear in some chunk
|
|
46
|
+
joined = " ".join(chunks)
|
|
47
|
+
assert para_a in joined
|
|
48
|
+
assert para_b in joined
|
|
49
|
+
assert para_c in joined
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class TestChunkTextSingleNewlines:
|
|
53
|
+
"""Text with only single newlines (e.g. trafilatura output)."""
|
|
54
|
+
|
|
55
|
+
def test_splits_on_single_newlines(self):
|
|
56
|
+
lines = [f"Line {i} " + "x" * 100 for i in range(30)]
|
|
57
|
+
text = "\n".join(lines)
|
|
58
|
+
chunks = chunk_text(text, max_chars=500)
|
|
59
|
+
assert len(chunks) > 1
|
|
60
|
+
# All content preserved
|
|
61
|
+
for line in lines:
|
|
62
|
+
assert any(line.strip() in c for c in chunks)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class TestChunkTextSentenceBoundary:
|
|
66
|
+
"""Text with no newlines at all — should split on sentence boundaries."""
|
|
67
|
+
|
|
68
|
+
def test_splits_on_sentences(self):
|
|
69
|
+
sentences = [f"Sentence number {i}." for i in range(60)]
|
|
70
|
+
text = " ".join(sentences)
|
|
71
|
+
assert "\n" not in text
|
|
72
|
+
chunks = chunk_text(text, max_chars=500)
|
|
73
|
+
assert len(chunks) > 1
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class TestChunkTextMaxChars:
|
|
77
|
+
"""No chunk should exceed max_chars."""
|
|
78
|
+
|
|
79
|
+
def test_chunks_respect_max_chars(self):
|
|
80
|
+
text = ("word " * 1000).strip()
|
|
81
|
+
for max_c in [200, 500, 1000]:
|
|
82
|
+
chunks = chunk_text(text, max_chars=max_c)
|
|
83
|
+
for chunk in chunks:
|
|
84
|
+
assert len(chunk) <= max_c, (
|
|
85
|
+
f"Chunk length {len(chunk)} exceeds max_chars={max_c}"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
def test_custom_max_chars(self):
|
|
89
|
+
text = "Hello. " * 200
|
|
90
|
+
chunks = chunk_text(text, max_chars=100)
|
|
91
|
+
assert len(chunks) > 1
|
|
92
|
+
for chunk in chunks:
|
|
93
|
+
assert len(chunk) <= 100
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class TestChunkTextEmpty:
|
|
97
|
+
"""Edge case: empty or whitespace-only text."""
|
|
98
|
+
|
|
99
|
+
def test_empty_string(self):
|
|
100
|
+
result = chunk_text("")
|
|
101
|
+
assert result == [""]
|
|
102
|
+
|
|
103
|
+
def test_whitespace_only(self):
|
|
104
|
+
result = chunk_text(" ")
|
|
105
|
+
assert result == [" "]
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
# ── _content_hash ─────────────────────────────────────────────────────────────
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class TestContentHash:
|
|
112
|
+
def test_same_text_same_hash(self):
|
|
113
|
+
assert _content_hash("hello") == _content_hash("hello")
|
|
114
|
+
|
|
115
|
+
def test_different_text_different_hash(self):
|
|
116
|
+
assert _content_hash("hello") != _content_hash("world")
|
|
117
|
+
|
|
118
|
+
def test_returns_hex_string(self):
|
|
119
|
+
h = _content_hash("test")
|
|
120
|
+
assert isinstance(h, str)
|
|
121
|
+
assert len(h) == 64 # SHA-256 hex length
|
|
122
|
+
int(h, 16) # valid hex
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# ── _normalised_hash ──────────────────────────────────────────────────────────
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class TestNormalisedHash:
|
|
129
|
+
def test_ignores_case(self):
|
|
130
|
+
assert _normalised_hash("Hello World") == _normalised_hash("hello world")
|
|
131
|
+
|
|
132
|
+
def test_ignores_extra_whitespace(self):
|
|
133
|
+
assert _normalised_hash("a b c") == _normalised_hash("a b c")
|
|
134
|
+
|
|
135
|
+
def test_ignores_leading_trailing_whitespace(self):
|
|
136
|
+
assert _normalised_hash(" hello ") == _normalised_hash("hello")
|
|
137
|
+
|
|
138
|
+
def test_ignores_newlines_vs_spaces(self):
|
|
139
|
+
assert _normalised_hash("hello\nworld") == _normalised_hash("hello world")
|
|
140
|
+
|
|
141
|
+
def test_differs_for_different_content(self):
|
|
142
|
+
assert _normalised_hash("alpha") != _normalised_hash("beta")
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# ── _simhash ──────────────────────────────────────────────────────────────────
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class TestSimhash:
|
|
149
|
+
def test_identical_text_distance_zero(self):
|
|
150
|
+
text = "The quick brown fox jumps over the lazy dog"
|
|
151
|
+
h1 = _simhash(text)
|
|
152
|
+
h2 = _simhash(text)
|
|
153
|
+
assert _hamming_distance(h1, h2) == 0
|
|
154
|
+
|
|
155
|
+
def test_similar_text_smaller_than_different(self):
|
|
156
|
+
t1 = "The quick brown fox jumps over the lazy dog"
|
|
157
|
+
t2 = "The quick brown fox leaps over the lazy dog"
|
|
158
|
+
t3 = "Lorem ipsum dolor sit amet consectetur adipiscing elit"
|
|
159
|
+
d_similar = _hamming_distance(_simhash(t1), _simhash(t2))
|
|
160
|
+
d_different = _hamming_distance(_simhash(t1), _simhash(t3))
|
|
161
|
+
assert d_similar < d_different, f"Similar ({d_similar}) should be < different ({d_different})"
|
|
162
|
+
|
|
163
|
+
def test_different_text_large_distance(self):
|
|
164
|
+
t1 = "The quick brown fox jumps over the lazy dog"
|
|
165
|
+
t2 = "Lorem ipsum dolor sit amet consectetur adipiscing elit"
|
|
166
|
+
d = _hamming_distance(_simhash(t1), _simhash(t2))
|
|
167
|
+
assert d > 5, f"Expected large distance, got {d}"
|
|
168
|
+
|
|
169
|
+
def test_returns_int(self):
|
|
170
|
+
assert isinstance(_simhash("test text here"), int)
|
|
171
|
+
|
|
172
|
+
def test_short_text_does_not_crash(self):
|
|
173
|
+
# Short text triggers character-level fallback
|
|
174
|
+
h = _simhash("hi")
|
|
175
|
+
assert isinstance(h, int)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
# ── _hamming_distance ─────────────────────────────────────────────────────────
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class TestHammingDistance:
|
|
182
|
+
def test_identical_values(self):
|
|
183
|
+
assert _hamming_distance(0b1010, 0b1010) == 0
|
|
184
|
+
|
|
185
|
+
def test_one_bit_difference(self):
|
|
186
|
+
assert _hamming_distance(0b1010, 0b1011) == 1
|
|
187
|
+
|
|
188
|
+
def test_all_bits_different(self):
|
|
189
|
+
assert _hamming_distance(0b0000, 0b1111) == 4
|
|
190
|
+
|
|
191
|
+
def test_known_pattern(self):
|
|
192
|
+
# 0xFF ^ 0x00 = 0xFF → 8 bits set
|
|
193
|
+
assert _hamming_distance(0xFF, 0x00) == 8
|
|
194
|
+
|
|
195
|
+
def test_symmetric(self):
|
|
196
|
+
assert _hamming_distance(42, 99) == _hamming_distance(99, 42)
|
|
197
|
+
|
|
198
|
+
def test_zero_zero(self):
|
|
199
|
+
assert _hamming_distance(0, 0) == 0
|