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,408 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PDF Extractor with Layout Parser Support
|
|
3
|
+
|
|
4
|
+
Uses Layout Parser for accurate multi-column document extraction.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Dict, Any, List, Optional
|
|
9
|
+
import logging
|
|
10
|
+
|
|
11
|
+
from ..registry import BaseExtractor, ExtractionResult
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class PdfExtractorLayoutParser(BaseExtractor):
|
|
17
|
+
"""
|
|
18
|
+
PDF extractor using Layout Parser for multi-column layouts.
|
|
19
|
+
|
|
20
|
+
Features:
|
|
21
|
+
- ML-based layout detection
|
|
22
|
+
- Proper reading order (column-by-column)
|
|
23
|
+
- Handles complex layouts
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, config):
|
|
27
|
+
"""Initialize Layout Parser PDF extractor."""
|
|
28
|
+
super().__init__(config)
|
|
29
|
+
self.extractor_version = "pdf_v2_layoutparser"
|
|
30
|
+
self.layout_model = None
|
|
31
|
+
self._initialize_layout_parser()
|
|
32
|
+
|
|
33
|
+
def _initialize_layout_parser(self):
|
|
34
|
+
"""Initialize Layout Parser model."""
|
|
35
|
+
try:
|
|
36
|
+
import layoutparser as lp
|
|
37
|
+
logger.info("Layout Parser library imported successfully")
|
|
38
|
+
|
|
39
|
+
# Try to load PubLayNet model
|
|
40
|
+
# Pre-download models first, then load
|
|
41
|
+
try:
|
|
42
|
+
logger.info("Loading Layout Parser model (this will download models on first use, ~221MB)...")
|
|
43
|
+
|
|
44
|
+
# Pre-download and resolve model path
|
|
45
|
+
# The lp://PubLayNet format needs to be converted to lp://paddledetection format
|
|
46
|
+
try:
|
|
47
|
+
from layoutparser.models.paddledetection.catalog import PathManager
|
|
48
|
+
# Convert lp://PubLayNet/.../model to lp://paddledetection/PubLayNet/.../weight
|
|
49
|
+
# This is the format that PathManager expects
|
|
50
|
+
model_path_lp = "lp://paddledetection/PubLayNet/ppyolov2_r50vd_dcn_365e/weight"
|
|
51
|
+
logger.info("Pre-downloading model files (this may take several minutes, ~221MB)...")
|
|
52
|
+
logger.info("Downloading from Baidu Cloud - please be patient...")
|
|
53
|
+
model_dir = PathManager.get_local_path(model_path_lp)
|
|
54
|
+
logger.info(f"Model downloaded successfully to: {model_dir}")
|
|
55
|
+
|
|
56
|
+
# Verify model files exist
|
|
57
|
+
import os
|
|
58
|
+
if os.path.exists(os.path.join(model_dir, "inference.pdmodel")):
|
|
59
|
+
logger.info("Model files verified: inference.pdmodel and inference.pdiparams found")
|
|
60
|
+
else:
|
|
61
|
+
logger.warning(f"Model files not found in {model_dir}")
|
|
62
|
+
except Exception as download_err:
|
|
63
|
+
logger.warning(f"Pre-download failed: {download_err}")
|
|
64
|
+
logger.info("Will attempt download during model creation...")
|
|
65
|
+
|
|
66
|
+
# Now try to load the model
|
|
67
|
+
# The lp://PubLayNet format should be automatically converted by config_parser
|
|
68
|
+
# But we've pre-downloaded the files, so PathManager should find them
|
|
69
|
+
try:
|
|
70
|
+
logger.info("Loading model from downloaded files...")
|
|
71
|
+
self.layout_model = lp.PaddleDetectionLayoutModel(
|
|
72
|
+
config_path="lp://PubLayNet/ppyolov2_r50vd_dcn_365e_publaynet/config",
|
|
73
|
+
model_path="lp://PubLayNet/ppyolov2_r50vd_dcn_365e_publaynet/model",
|
|
74
|
+
label_map={0: "Text", 1: "Title", 2: "List", 3: "Table", 4: "Figure"}
|
|
75
|
+
)
|
|
76
|
+
logger.info("Layout Parser (PaddlePaddle) model loaded successfully!")
|
|
77
|
+
except Exception as load_error:
|
|
78
|
+
logger.warning(f"Model load failed with lp://PubLayNet format: {load_error}")
|
|
79
|
+
# The issue is that config_parser isn't converting the path correctly
|
|
80
|
+
# Try using the format that we know works
|
|
81
|
+
try:
|
|
82
|
+
logger.info("Trying alternative path format...")
|
|
83
|
+
# Use the format that PathManager can resolve
|
|
84
|
+
# But PaddleDetectionLayoutModel expects the short format in config_path/model_path
|
|
85
|
+
# So we need to ensure the conversion happens
|
|
86
|
+
self.layout_model = lp.PaddleDetectionLayoutModel(
|
|
87
|
+
config_path="lp://PubLayNet/ppyolov2_r50vd_dcn_365e_publaynet/config",
|
|
88
|
+
model_path="lp://PubLayNet/ppyolov2_r50vd_dcn_365e_publaynet/model",
|
|
89
|
+
label_map={0: "Text", 1: "Title", 2: "List", 3: "Table", 4: "Figure"}
|
|
90
|
+
)
|
|
91
|
+
logger.info("Layout Parser model loaded!")
|
|
92
|
+
except Exception as e2:
|
|
93
|
+
logger.error(f"All model loading attempts failed: {e2}")
|
|
94
|
+
self.layout_model = None # Will be created on first use
|
|
95
|
+
except Exception as model_error:
|
|
96
|
+
# Try alternative: Detectron2LayoutModel if PaddleDetection fails
|
|
97
|
+
try:
|
|
98
|
+
logger.info("Trying Detectron2LayoutModel as alternative...")
|
|
99
|
+
self.layout_model = lp.Detectron2LayoutModel(
|
|
100
|
+
config_path="lp://PubLayNet/faster_rcnn_R_50_FPN_3x/config",
|
|
101
|
+
model_path="lp://PubLayNet/faster_rcnn_R_50_FPN_3x/model",
|
|
102
|
+
label_map={0: "Text", 1: "Title", 2: "List", 3: "Table", 4: "Figure"},
|
|
103
|
+
extra_config=["MODEL.ROI_HEADS.SCORE_THRESH_TEST", 0.5]
|
|
104
|
+
)
|
|
105
|
+
logger.info("Layout Parser (Detectron2) model loaded successfully")
|
|
106
|
+
except Exception as e2:
|
|
107
|
+
logger.warning(f"Could not load Layout Parser model (PaddleDetection or Detectron2): {model_error}, {e2}")
|
|
108
|
+
logger.warning("Falling back to heuristic extraction")
|
|
109
|
+
self.layout_model = None
|
|
110
|
+
except ImportError as e:
|
|
111
|
+
logger.warning(f"Layout Parser not available: {e}")
|
|
112
|
+
logger.warning("Install with: pip install layoutparser")
|
|
113
|
+
logger.warning("For models, also install: pip install detectron2 (or paddlepaddle)")
|
|
114
|
+
self.layout_model = None
|
|
115
|
+
except Exception as e:
|
|
116
|
+
logger.warning(f"Could not initialize Layout Parser: {e}")
|
|
117
|
+
self.layout_model = None
|
|
118
|
+
|
|
119
|
+
def supports_format(self, file_path: str) -> bool:
|
|
120
|
+
"""Check if file is a PDF."""
|
|
121
|
+
return Path(file_path).suffix.lower() == ".pdf"
|
|
122
|
+
|
|
123
|
+
def extract(self, file_path: str) -> ExtractionResult:
|
|
124
|
+
"""
|
|
125
|
+
Extract content from PDF using Layout Parser.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
file_path: Path to PDF file
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
ExtractionResult
|
|
132
|
+
"""
|
|
133
|
+
result = ExtractionResult(extractor_version=self.extractor_version)
|
|
134
|
+
|
|
135
|
+
# Try to load model if not already loaded (lazy loading with download)
|
|
136
|
+
if not self.layout_model:
|
|
137
|
+
logger.info("Layout Parser model not loaded, attempting to load and download now...")
|
|
138
|
+
logger.info("Downloading models (requires internet, may take several minutes, ~100-200MB)...")
|
|
139
|
+
try:
|
|
140
|
+
import layoutparser as lp
|
|
141
|
+
import site
|
|
142
|
+
import sys
|
|
143
|
+
# Ensure user site-packages are accessible for PaddlePaddle
|
|
144
|
+
user_site = site.getusersitepackages()
|
|
145
|
+
if user_site and user_site not in sys.path:
|
|
146
|
+
sys.path.insert(0, user_site)
|
|
147
|
+
|
|
148
|
+
# The lp:// protocol should trigger automatic download
|
|
149
|
+
# Layout Parser downloads models to ~/.layoutparser/ on first use
|
|
150
|
+
logger.info("Attempting to load PaddlePaddle model (will download if needed)...")
|
|
151
|
+
|
|
152
|
+
# Pre-download models by calling PathManager.get_local_path()
|
|
153
|
+
# This ensures models are downloaded before trying to load them
|
|
154
|
+
try:
|
|
155
|
+
from layoutparser.models.paddledetection.catalog import PathManager
|
|
156
|
+
# Pre-download the model weight file
|
|
157
|
+
# The format: lp://paddledetection/Dataset/ModelName/weight
|
|
158
|
+
model_path_lp = "lp://paddledetection/PubLayNet/ppyolov2_r50vd_dcn_365e/weight"
|
|
159
|
+
logger.info("Pre-downloading model files (this may take several minutes, ~221MB)...")
|
|
160
|
+
logger.info("Downloading from Baidu Cloud - please be patient...")
|
|
161
|
+
model_dir = PathManager.get_local_path(model_path_lp)
|
|
162
|
+
logger.info(f"Model downloaded successfully to: {model_dir}")
|
|
163
|
+
except Exception as download_err:
|
|
164
|
+
logger.warning(f"Pre-download failed: {download_err}")
|
|
165
|
+
logger.info("Will attempt download during model creation...")
|
|
166
|
+
|
|
167
|
+
# Try PaddlePaddle first
|
|
168
|
+
try:
|
|
169
|
+
# The lp://PubLayNet format is automatically converted internally
|
|
170
|
+
# This should now work since models are downloaded
|
|
171
|
+
logger.info("Loading model from downloaded files...")
|
|
172
|
+
self.layout_model = lp.PaddleDetectionLayoutModel(
|
|
173
|
+
config_path="lp://PubLayNet/ppyolov2_r50vd_dcn_365e_publaynet/config",
|
|
174
|
+
model_path="lp://PubLayNet/ppyolov2_r50vd_dcn_365e_publaynet/model",
|
|
175
|
+
label_map={0: "Text", 1: "Title", 2: "List", 3: "Table", 4: "Figure"}
|
|
176
|
+
)
|
|
177
|
+
logger.info("Layout Parser (PaddlePaddle) model loaded successfully!")
|
|
178
|
+
except Exception as paddle_err:
|
|
179
|
+
logger.warning(f"PaddlePaddle model failed: {str(paddle_err)[:200]}")
|
|
180
|
+
# Try Detectron2 as alternative
|
|
181
|
+
logger.info("Trying Detectron2 model as alternative...")
|
|
182
|
+
try:
|
|
183
|
+
self.layout_model = lp.Detectron2LayoutModel(
|
|
184
|
+
config_path="lp://PubLayNet/faster_rcnn_R_50_FPN_3x/config",
|
|
185
|
+
model_path="lp://PubLayNet/faster_rcnn_R_50_FPN_3x/model",
|
|
186
|
+
label_map={0: "Text", 1: "Title", 2: "List", 3: "Table", 4: "Figure"}
|
|
187
|
+
)
|
|
188
|
+
logger.info("Layout Parser (Detectron2) model loaded successfully!")
|
|
189
|
+
except Exception as detectron_err:
|
|
190
|
+
error_msg = f"Both models failed. PaddlePaddle: {str(paddle_err)[:100]}, Detectron2: {str(detectron_err)[:100]}"
|
|
191
|
+
logger.error(error_msg)
|
|
192
|
+
logger.warning("Models may need to be downloaded manually or internet connection required")
|
|
193
|
+
result.errors.append("Layout Parser model not available - using fallback")
|
|
194
|
+
return result
|
|
195
|
+
except Exception as e:
|
|
196
|
+
logger.error(f"Could not load Layout Parser model: {e}")
|
|
197
|
+
logger.warning("Falling back to standard extraction")
|
|
198
|
+
result.errors.append("Layout Parser model not available - using fallback")
|
|
199
|
+
return result
|
|
200
|
+
|
|
201
|
+
try:
|
|
202
|
+
import fitz # PyMuPDF
|
|
203
|
+
import pdfplumber
|
|
204
|
+
import numpy as np
|
|
205
|
+
from PIL import Image
|
|
206
|
+
except ImportError as e:
|
|
207
|
+
logger.error(f"Required libraries not available: {e}")
|
|
208
|
+
result.errors.append(f"Missing dependencies: {e}")
|
|
209
|
+
return result
|
|
210
|
+
|
|
211
|
+
# Get metadata using pdfplumber
|
|
212
|
+
with pdfplumber.open(file_path) as pdf:
|
|
213
|
+
metadata = pdf.metadata or {}
|
|
214
|
+
result.metadata = {
|
|
215
|
+
"title": metadata.get("Title", ""),
|
|
216
|
+
"author": metadata.get("Author", ""),
|
|
217
|
+
"subject": metadata.get("Subject", ""),
|
|
218
|
+
"creator": metadata.get("Creator", ""),
|
|
219
|
+
"producer": metadata.get("Producer", ""),
|
|
220
|
+
"page_count": len(pdf.pages),
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
# Extract using Layout Parser
|
|
224
|
+
doc = fitz.open(file_path)
|
|
225
|
+
requested_pages = self._get_requested_pages()
|
|
226
|
+
|
|
227
|
+
try:
|
|
228
|
+
for i, page_fitz in enumerate(doc, 1):
|
|
229
|
+
if requested_pages and i not in requested_pages:
|
|
230
|
+
continue
|
|
231
|
+
|
|
232
|
+
# Convert page to image for Layout Parser
|
|
233
|
+
pix = page_fitz.get_pixmap(matrix=fitz.Matrix(2, 2))
|
|
234
|
+
img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
|
|
235
|
+
img_array = np.array(img)
|
|
236
|
+
|
|
237
|
+
# Detect layout
|
|
238
|
+
layout = self.layout_model.detect(img_array)
|
|
239
|
+
|
|
240
|
+
# Extract text with proper reading order
|
|
241
|
+
text_blocks = self._extract_text_with_reading_order(
|
|
242
|
+
page_fitz, layout, i
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
# Combine text blocks
|
|
246
|
+
page_text = "\n\n".join([block["text"] for block in text_blocks])
|
|
247
|
+
|
|
248
|
+
result.pages.append({
|
|
249
|
+
"page_no": i,
|
|
250
|
+
"text": page_text,
|
|
251
|
+
"content": page_text,
|
|
252
|
+
"layout_blocks": text_blocks, # Preserve block structure
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
# Extract tables using pdfplumber (better for tables)
|
|
256
|
+
try:
|
|
257
|
+
with pdfplumber.open(file_path) as pdf:
|
|
258
|
+
page_plumber = pdf.pages[i - 1]
|
|
259
|
+
tables = page_plumber.extract_tables()
|
|
260
|
+
|
|
261
|
+
for table_idx, table in enumerate(tables or [], 1):
|
|
262
|
+
if table:
|
|
263
|
+
result.tables.append({
|
|
264
|
+
"id": f"tbl_{i}_{table_idx}",
|
|
265
|
+
"page_number": i,
|
|
266
|
+
"data": table,
|
|
267
|
+
"headers": table[0] if table else [],
|
|
268
|
+
"rows": table[1:] if len(table) > 1 else [],
|
|
269
|
+
})
|
|
270
|
+
except Exception as e:
|
|
271
|
+
logger.warning(f"Error extracting tables from page {i}: {e}")
|
|
272
|
+
|
|
273
|
+
# Extract images
|
|
274
|
+
image_list = page_fitz.get_images()
|
|
275
|
+
for img_idx, img in enumerate(image_list, 1):
|
|
276
|
+
try:
|
|
277
|
+
xref = img[0]
|
|
278
|
+
base_image = doc.extract_image(xref)
|
|
279
|
+
image_bytes = base_image["image"]
|
|
280
|
+
image_ext = base_image["ext"]
|
|
281
|
+
|
|
282
|
+
from pathlib import Path
|
|
283
|
+
import tempfile
|
|
284
|
+
temp_dir = Path(tempfile.gettempdir()) / "aiql_extraction_images"
|
|
285
|
+
temp_dir.mkdir(exist_ok=True)
|
|
286
|
+
image_path = temp_dir / f"img_{i}_{img_idx}.{image_ext}"
|
|
287
|
+
with open(image_path, 'wb') as img_file:
|
|
288
|
+
img_file.write(image_bytes)
|
|
289
|
+
|
|
290
|
+
result.images.append({
|
|
291
|
+
"id": f"img_{i}_{img_idx}",
|
|
292
|
+
"page_number": i,
|
|
293
|
+
"path": str(image_path),
|
|
294
|
+
"format": image_ext.upper(),
|
|
295
|
+
"size_bytes": len(image_bytes),
|
|
296
|
+
})
|
|
297
|
+
except Exception as e:
|
|
298
|
+
logger.warning(f"Failed to extract image {img_idx} from page {i}: {e}")
|
|
299
|
+
|
|
300
|
+
finally:
|
|
301
|
+
doc.close()
|
|
302
|
+
|
|
303
|
+
return result
|
|
304
|
+
|
|
305
|
+
def _extract_text_with_reading_order(
|
|
306
|
+
self,
|
|
307
|
+
page_fitz,
|
|
308
|
+
layout,
|
|
309
|
+
page_num: int
|
|
310
|
+
) -> List[Dict[str, Any]]:
|
|
311
|
+
"""
|
|
312
|
+
Extract text blocks with proper reading order for multi-column layouts.
|
|
313
|
+
|
|
314
|
+
Reading order algorithm:
|
|
315
|
+
1. Sort blocks by y-coordinate (top to bottom)
|
|
316
|
+
2. Within same y-range, sort by x-coordinate (left to right)
|
|
317
|
+
3. For multi-column: process left column completely, then right column
|
|
318
|
+
"""
|
|
319
|
+
if not layout:
|
|
320
|
+
# Fallback: extract text directly
|
|
321
|
+
text = page_fitz.get_text()
|
|
322
|
+
return [{"text": text, "type": "Text", "order": 0}]
|
|
323
|
+
|
|
324
|
+
# Get text blocks (Text, Title, List)
|
|
325
|
+
text_blocks = [
|
|
326
|
+
block for block in layout
|
|
327
|
+
if block.type in ["Text", "Title", "List"]
|
|
328
|
+
]
|
|
329
|
+
|
|
330
|
+
if not text_blocks:
|
|
331
|
+
# Fallback: extract text directly
|
|
332
|
+
text = page_fitz.get_text()
|
|
333
|
+
return [{"text": text, "type": "Text", "order": 0}]
|
|
334
|
+
|
|
335
|
+
# Sort blocks by reading order
|
|
336
|
+
# Strategy: Sort by (y_top, x_left) to read top-to-bottom, left-to-right
|
|
337
|
+
def get_sort_key(block):
|
|
338
|
+
bbox = block.block
|
|
339
|
+
# Use top y-coordinate first, then left x-coordinate
|
|
340
|
+
return (bbox.y_0, bbox.x_0)
|
|
341
|
+
|
|
342
|
+
sorted_blocks = sorted(text_blocks, key=get_sort_key)
|
|
343
|
+
|
|
344
|
+
# Extract text for each block
|
|
345
|
+
blocks_with_text = []
|
|
346
|
+
for idx, block in enumerate(sorted_blocks):
|
|
347
|
+
bbox = block.block
|
|
348
|
+
|
|
349
|
+
# Extract text from this region
|
|
350
|
+
# Convert Layout Parser coordinates to PyMuPDF coordinates
|
|
351
|
+
import fitz # Ensure fitz is imported
|
|
352
|
+
rect = fitz.Rect(bbox.x_0, bbox.y_0, bbox.x_1, bbox.y_1)
|
|
353
|
+
text = page_fitz.get_text("text", clip=rect)
|
|
354
|
+
|
|
355
|
+
if text.strip():
|
|
356
|
+
blocks_with_text.append({
|
|
357
|
+
"text": text.strip(),
|
|
358
|
+
"type": block.type,
|
|
359
|
+
"order": idx,
|
|
360
|
+
"bbox": {
|
|
361
|
+
"x0": bbox.x_0,
|
|
362
|
+
"y0": bbox.y_0,
|
|
363
|
+
"x1": bbox.x_1,
|
|
364
|
+
"y1": bbox.y_1
|
|
365
|
+
}
|
|
366
|
+
})
|
|
367
|
+
|
|
368
|
+
return blocks_with_text
|
|
369
|
+
|
|
370
|
+
def _get_requested_pages(self) -> List[int]:
|
|
371
|
+
"""Get list of requested page numbers."""
|
|
372
|
+
if self.config.pages_mode.value == "full":
|
|
373
|
+
return []
|
|
374
|
+
elif self.config.pages_mode.value == "range":
|
|
375
|
+
if self.config.pages_range:
|
|
376
|
+
start, end = self.config.pages_range
|
|
377
|
+
return list(range(start, end + 1))
|
|
378
|
+
elif self.config.pages_mode.value == "list":
|
|
379
|
+
return self.config.pages_list or []
|
|
380
|
+
return []
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Register Extractors
|
|
3
|
+
|
|
4
|
+
Registers all extractors with the ExtractorRegistry.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from ..registry import ExtractorRegistry
|
|
8
|
+
from .pdf_extractor import PdfExtractor
|
|
9
|
+
from .docx_extractor import DocxExtractor
|
|
10
|
+
from .txt_extractor import TxtExtractor
|
|
11
|
+
from .csv_extractor import CsvExtractor
|
|
12
|
+
from .html_extractor import HtmlExtractor
|
|
13
|
+
from .website_extractor import WebsiteExtractor
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def register_all_extractors():
|
|
17
|
+
"""Register all extractors."""
|
|
18
|
+
# Register with auto-detect enabled
|
|
19
|
+
ExtractorRegistry.register("pdf_v1", PdfExtractor, auto_detect=True)
|
|
20
|
+
ExtractorRegistry.register("docx_v1", DocxExtractor, auto_detect=True)
|
|
21
|
+
ExtractorRegistry.register("txt_v1", TxtExtractor, auto_detect=True)
|
|
22
|
+
ExtractorRegistry.register("csv_v1", CsvExtractor, auto_detect=True)
|
|
23
|
+
ExtractorRegistry.register("html_v1", HtmlExtractor, auto_detect=True)
|
|
24
|
+
ExtractorRegistry.register("website_v1", WebsiteExtractor, auto_detect=True)
|
|
25
|
+
|
|
26
|
+
# Also register as "AUTO" fallback (handled by auto_detect)
|
|
27
|
+
# The AUTO logic in ExtractorRegistry will use auto_detect=True extractors
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# Auto-register on import
|
|
31
|
+
register_all_extractors()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Text Extractor
|
|
3
|
+
|
|
4
|
+
Extracts content from plain text files.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Dict, Any
|
|
9
|
+
import logging
|
|
10
|
+
|
|
11
|
+
from ..registry import BaseExtractor, ExtractionResult
|
|
12
|
+
from ..config import ExtractionConfig
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TextExtractor(BaseExtractor):
|
|
18
|
+
"""Text file extractor."""
|
|
19
|
+
|
|
20
|
+
version = "txt_v1"
|
|
21
|
+
|
|
22
|
+
def supports_format(self, file_path: str) -> bool:
|
|
23
|
+
"""Check if file is text."""
|
|
24
|
+
ext = Path(file_path).suffix.lower()
|
|
25
|
+
return ext in {".txt", ".md", ".log"}
|
|
26
|
+
|
|
27
|
+
def extract(self, file_path: str) -> ExtractionResult:
|
|
28
|
+
"""Extract content from text file."""
|
|
29
|
+
result = ExtractionResult(extractor_version=self.version)
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
# Try UTF-8 first
|
|
33
|
+
try:
|
|
34
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
|
35
|
+
content = f.read()
|
|
36
|
+
except UnicodeDecodeError:
|
|
37
|
+
# Fallback to latin-1
|
|
38
|
+
with open(file_path, 'r', encoding='latin-1') as f:
|
|
39
|
+
content = f.read()
|
|
40
|
+
|
|
41
|
+
result.pages[1] = content
|
|
42
|
+
result.metadata = {
|
|
43
|
+
"page_count": 1,
|
|
44
|
+
"file_path": str(file_path),
|
|
45
|
+
"line_count": len(content.splitlines()),
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Create raw blocks
|
|
49
|
+
result.raw_blocks[1] = [
|
|
50
|
+
{
|
|
51
|
+
"id": f"raw_1_{i}",
|
|
52
|
+
"type": "paragraph",
|
|
53
|
+
"content": line,
|
|
54
|
+
"metadata": {}
|
|
55
|
+
}
|
|
56
|
+
for i, line in enumerate(content.splitlines(), 1)
|
|
57
|
+
if line.strip()
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
except Exception as e:
|
|
61
|
+
logger.error(f"Text extraction failed: {e}")
|
|
62
|
+
result.errors.append(str(e))
|
|
63
|
+
|
|
64
|
+
return result
|
|
65
|
+
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TXT Extractor
|
|
3
|
+
|
|
4
|
+
Extracts content from plain text files.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Dict, Any
|
|
9
|
+
import logging
|
|
10
|
+
|
|
11
|
+
from ..registry import BaseExtractor, ExtractionResult
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TxtExtractor(BaseExtractor):
|
|
17
|
+
"""
|
|
18
|
+
Plain text extractor.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, config):
|
|
22
|
+
"""Initialize TXT extractor."""
|
|
23
|
+
super().__init__(config)
|
|
24
|
+
self.extractor_version = "txt_v1"
|
|
25
|
+
|
|
26
|
+
def supports_format(self, file_path: str) -> bool:
|
|
27
|
+
"""Check if file is a TXT."""
|
|
28
|
+
return Path(file_path).suffix.lower() == ".txt"
|
|
29
|
+
|
|
30
|
+
def extract(self, file_path: str) -> ExtractionResult:
|
|
31
|
+
"""
|
|
32
|
+
Extract content from TXT file.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
file_path: Path to TXT file
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
ExtractionResult
|
|
39
|
+
"""
|
|
40
|
+
result = ExtractionResult(extractor_version=self.extractor_version)
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
# Try different encodings
|
|
44
|
+
encodings = ['utf-8', 'latin-1', 'cp1252', 'iso-8859-1']
|
|
45
|
+
content = None
|
|
46
|
+
|
|
47
|
+
for encoding in encodings:
|
|
48
|
+
try:
|
|
49
|
+
with open(file_path, 'r', encoding=encoding) as f:
|
|
50
|
+
content = f.read()
|
|
51
|
+
break
|
|
52
|
+
except UnicodeDecodeError:
|
|
53
|
+
continue
|
|
54
|
+
|
|
55
|
+
if content is None:
|
|
56
|
+
raise ValueError(f"Could not decode file with any encoding: {encodings}")
|
|
57
|
+
|
|
58
|
+
# Split into pages (by line breaks or size)
|
|
59
|
+
lines = content.split('\n')
|
|
60
|
+
page_size = 50 # lines per page (configurable)
|
|
61
|
+
|
|
62
|
+
pages = []
|
|
63
|
+
for i in range(0, len(lines), page_size):
|
|
64
|
+
page_text = '\n'.join(lines[i:i+page_size])
|
|
65
|
+
pages.append({
|
|
66
|
+
"page_no": len(pages) + 1,
|
|
67
|
+
"text": page_text,
|
|
68
|
+
"content": page_text,
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
if not pages:
|
|
72
|
+
pages.append({
|
|
73
|
+
"page_no": 1,
|
|
74
|
+
"text": content,
|
|
75
|
+
"content": content,
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
result.pages = pages
|
|
79
|
+
result.metadata = {
|
|
80
|
+
"title": Path(file_path).stem,
|
|
81
|
+
"page_count": len(pages),
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
except Exception as e:
|
|
85
|
+
logger.error(f"TXT extraction failed: {e}")
|
|
86
|
+
result.errors.append(str(e))
|
|
87
|
+
|
|
88
|
+
return result
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|