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,610 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LLM-Based Document Extraction Module
|
|
3
|
+
|
|
4
|
+
This module provides intelligent document extraction using LLMs to:
|
|
5
|
+
- Extract text with proper reading order (handles multi-column layouts)
|
|
6
|
+
- Extract tables with structure preservation
|
|
7
|
+
- Extract images with metadata
|
|
8
|
+
- Extract named entities (NER)
|
|
9
|
+
- Generate semantic chunks
|
|
10
|
+
- Provide structured JSON output
|
|
11
|
+
|
|
12
|
+
This is more expensive than heuristic approaches but provides superior quality.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
import logging
|
|
17
|
+
import base64
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from typing import Dict, List, Any, Optional, Union
|
|
20
|
+
from dataclasses import dataclass, asdict
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class ExtractedTable:
|
|
27
|
+
"""Represents an extracted table with structure."""
|
|
28
|
+
table_index: int
|
|
29
|
+
page_number: int
|
|
30
|
+
headers: List[str]
|
|
31
|
+
rows: List[List[str]]
|
|
32
|
+
title: Optional[str] = None
|
|
33
|
+
caption: Optional[str] = None
|
|
34
|
+
spatial_info: Optional[Dict[str, float]] = None # x, y, width, height
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass
|
|
38
|
+
class ExtractedImage:
|
|
39
|
+
"""Represents an extracted image with metadata."""
|
|
40
|
+
image_index: int
|
|
41
|
+
page_number: int
|
|
42
|
+
filename: str
|
|
43
|
+
format: str # PNG, JPEG, etc.
|
|
44
|
+
width: int
|
|
45
|
+
height: int
|
|
46
|
+
file_size: int
|
|
47
|
+
spatial_info: Optional[Dict[str, float]] = None # x, y, width, height
|
|
48
|
+
description: Optional[str] = None # LLM-generated description
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass
|
|
52
|
+
class ExtractedEntity:
|
|
53
|
+
"""Represents a named entity extracted from the document."""
|
|
54
|
+
entity_type: str # PERSON, ORGANIZATION, LOCATION, etc.
|
|
55
|
+
entity_name: str
|
|
56
|
+
canonical_name: Optional[str] = None
|
|
57
|
+
start_char: Optional[int] = None
|
|
58
|
+
end_char: Optional[int] = None
|
|
59
|
+
confidence: Optional[float] = None
|
|
60
|
+
context: Optional[str] = None # Surrounding text
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass
|
|
64
|
+
class DocumentChunk:
|
|
65
|
+
"""Represents a semantic chunk of the document."""
|
|
66
|
+
chunk_index: int
|
|
67
|
+
content: str
|
|
68
|
+
chunk_type: str # "paragraph", "section", "table_reference", etc.
|
|
69
|
+
start_char: Optional[int] = None
|
|
70
|
+
end_char: Optional[int] = None
|
|
71
|
+
page_number: Optional[int] = None
|
|
72
|
+
entities: Optional[List[ExtractedEntity]] = None
|
|
73
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@dataclass
|
|
77
|
+
class LLMExtractionResult:
|
|
78
|
+
"""Complete extraction result from LLM."""
|
|
79
|
+
text_content: str
|
|
80
|
+
tables: List[ExtractedTable]
|
|
81
|
+
images: List[ExtractedImage]
|
|
82
|
+
entities: List[ExtractedEntity]
|
|
83
|
+
chunks: List[DocumentChunk]
|
|
84
|
+
metadata: Dict[str, Any]
|
|
85
|
+
reading_order_preserved: bool = True
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class LLMDocumentExtractor:
|
|
89
|
+
"""LLM-based document extractor for high-quality extraction."""
|
|
90
|
+
|
|
91
|
+
def __init__(self, llm_provider=None, llm_model: str = "gpt-3.5-turbo", temperature: float = 0.0):
|
|
92
|
+
"""
|
|
93
|
+
Initialize LLM extractor.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
llm_provider: LLM provider instance (AIContextDBUniversalLLM)
|
|
97
|
+
llm_model: Model name (e.g., "gpt-4", "gpt-4-turbo", "claude-3-opus")
|
|
98
|
+
temperature: Temperature for LLM generation (0.0 for deterministic)
|
|
99
|
+
"""
|
|
100
|
+
self.llm_provider = llm_provider
|
|
101
|
+
self.llm_model = llm_model
|
|
102
|
+
self.temperature = temperature
|
|
103
|
+
|
|
104
|
+
if llm_provider is None:
|
|
105
|
+
try:
|
|
106
|
+
from ..llm.universal_llm import AIContextDBUniversalLLM
|
|
107
|
+
self.llm_provider = AIContextDBUniversalLLM()
|
|
108
|
+
except Exception as e:
|
|
109
|
+
logger.error(f"Failed to initialize LLM provider: {e}")
|
|
110
|
+
raise
|
|
111
|
+
|
|
112
|
+
def extract_from_pdf(self, pdf_path: Union[str, Path],
|
|
113
|
+
max_pages: Optional[int] = None,
|
|
114
|
+
extract_tables: bool = True,
|
|
115
|
+
extract_images: bool = True,
|
|
116
|
+
extract_entities: bool = True,
|
|
117
|
+
generate_chunks: bool = True,
|
|
118
|
+
chunk_strategy: str = "semantic") -> LLMExtractionResult:
|
|
119
|
+
"""
|
|
120
|
+
Extract structured information from PDF using LLM.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
pdf_path: Path to PDF file
|
|
124
|
+
max_pages: Maximum number of pages to process (None for all)
|
|
125
|
+
extract_tables: Whether to extract tables
|
|
126
|
+
extract_images: Whether to extract images
|
|
127
|
+
extract_entities: Whether to extract named entities
|
|
128
|
+
generate_chunks: Whether to generate semantic chunks
|
|
129
|
+
chunk_strategy: Chunking strategy ("semantic", "paragraph", "sentence")
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
LLMExtractionResult with all extracted information
|
|
133
|
+
"""
|
|
134
|
+
pdf_path = Path(pdf_path)
|
|
135
|
+
if not pdf_path.exists():
|
|
136
|
+
raise FileNotFoundError(f"PDF file not found: {pdf_path}")
|
|
137
|
+
|
|
138
|
+
logger.info(f"Starting LLM-based extraction from: {pdf_path}")
|
|
139
|
+
logger.info(f"Settings: tables={extract_tables}, images={extract_images}, "
|
|
140
|
+
f"entities={extract_entities}, chunks={generate_chunks}")
|
|
141
|
+
|
|
142
|
+
# Step 1: Extract raw content from PDF (text, tables, images with coordinates)
|
|
143
|
+
raw_content = self._extract_raw_content(pdf_path, max_pages)
|
|
144
|
+
|
|
145
|
+
# Step 2: Use LLM to process and structure the content
|
|
146
|
+
structured_result = self._llm_process_content(
|
|
147
|
+
raw_content,
|
|
148
|
+
extract_tables=extract_tables,
|
|
149
|
+
extract_images=extract_images,
|
|
150
|
+
extract_entities=extract_entities,
|
|
151
|
+
generate_chunks=generate_chunks,
|
|
152
|
+
chunk_strategy=chunk_strategy
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
return structured_result
|
|
156
|
+
|
|
157
|
+
def _extract_raw_content(self, pdf_path: Path, max_pages: Optional[int]) -> Dict[str, Any]:
|
|
158
|
+
"""Extract raw content from PDF (text, tables, images) for LLM processing."""
|
|
159
|
+
try:
|
|
160
|
+
import fitz # PyMuPDF
|
|
161
|
+
import pdfplumber
|
|
162
|
+
from PIL import Image as PILImage
|
|
163
|
+
import io
|
|
164
|
+
except ImportError as e:
|
|
165
|
+
logger.error(f"Required libraries not installed: {e}")
|
|
166
|
+
logger.error("Install: pip install pymupdf pdfplumber pillow")
|
|
167
|
+
raise
|
|
168
|
+
|
|
169
|
+
raw_content = {
|
|
170
|
+
'pages': [],
|
|
171
|
+
'metadata': {
|
|
172
|
+
'file_path': str(pdf_path),
|
|
173
|
+
'file_name': pdf_path.name,
|
|
174
|
+
'total_pages': 0
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
try:
|
|
179
|
+
# Open PDF with PyMuPDF
|
|
180
|
+
doc = fitz.open(pdf_path)
|
|
181
|
+
total_pages = len(doc)
|
|
182
|
+
pages_to_process = min(max_pages or total_pages, total_pages)
|
|
183
|
+
raw_content['metadata']['total_pages'] = total_pages
|
|
184
|
+
raw_content['metadata']['pages_processed'] = pages_to_process
|
|
185
|
+
|
|
186
|
+
# Open with pdfplumber for table extraction
|
|
187
|
+
pdf_plumber = pdfplumber.open(pdf_path)
|
|
188
|
+
|
|
189
|
+
for page_idx in range(pages_to_process):
|
|
190
|
+
page_data = {
|
|
191
|
+
'page_number': page_idx + 1,
|
|
192
|
+
'text_blocks': [],
|
|
193
|
+
'tables': [],
|
|
194
|
+
'images': []
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
# Extract text with spatial information
|
|
198
|
+
page_fitz = doc[page_idx]
|
|
199
|
+
page_plumber = pdf_plumber.pages[page_idx]
|
|
200
|
+
|
|
201
|
+
# Get text blocks with coordinates
|
|
202
|
+
text_blocks = page_fitz.get_text("blocks")
|
|
203
|
+
for block in text_blocks:
|
|
204
|
+
if len(block) >= 5:
|
|
205
|
+
block_text = block[4].strip()
|
|
206
|
+
if block_text:
|
|
207
|
+
page_data['text_blocks'].append({
|
|
208
|
+
'text': block_text,
|
|
209
|
+
'x': block[0],
|
|
210
|
+
'y': block[1],
|
|
211
|
+
'width': block[2] - block[0],
|
|
212
|
+
'height': block[3] - block[1]
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
# Extract tables
|
|
216
|
+
tables = page_plumber.extract_tables()
|
|
217
|
+
for table_idx, table_data in enumerate(tables):
|
|
218
|
+
if table_data and len(table_data) > 0:
|
|
219
|
+
headers = [str(cell).strip() if cell else "" for cell in table_data[0]] if table_data else []
|
|
220
|
+
rows = []
|
|
221
|
+
for row in table_data[1:]:
|
|
222
|
+
if row and any(cell for cell in row if cell):
|
|
223
|
+
rows.append([str(cell).strip() if cell else "" for cell in row])
|
|
224
|
+
|
|
225
|
+
if headers or rows:
|
|
226
|
+
# Get table bounding box
|
|
227
|
+
table_bbox = None
|
|
228
|
+
try:
|
|
229
|
+
page_tables = page_plumber.find_tables()
|
|
230
|
+
if table_idx < len(page_tables):
|
|
231
|
+
table_obj = page_tables[table_idx]
|
|
232
|
+
table_bbox = {
|
|
233
|
+
'x': table_obj.bbox[0],
|
|
234
|
+
'y': table_obj.bbox[1],
|
|
235
|
+
'width': table_obj.bbox[2] - table_obj.bbox[0],
|
|
236
|
+
'height': table_obj.bbox[3] - table_obj.bbox[1]
|
|
237
|
+
}
|
|
238
|
+
except:
|
|
239
|
+
pass
|
|
240
|
+
|
|
241
|
+
page_data['tables'].append({
|
|
242
|
+
'table_index': table_idx + 1,
|
|
243
|
+
'headers': headers,
|
|
244
|
+
'rows': rows,
|
|
245
|
+
'spatial_info': table_bbox
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
# Extract images
|
|
249
|
+
image_list = page_fitz.get_images(full=True)
|
|
250
|
+
for img_idx, img in enumerate(image_list):
|
|
251
|
+
try:
|
|
252
|
+
xref = img[0]
|
|
253
|
+
base_image = doc.extract_image(xref)
|
|
254
|
+
image_bytes = base_image["image"]
|
|
255
|
+
image_ext = base_image["ext"]
|
|
256
|
+
|
|
257
|
+
# Get image dimensions
|
|
258
|
+
image_obj = PILImage.open(io.BytesIO(image_bytes))
|
|
259
|
+
width, height = image_obj.size
|
|
260
|
+
|
|
261
|
+
page_data['images'].append({
|
|
262
|
+
'image_index': img_idx + 1,
|
|
263
|
+
'format': image_ext.upper(),
|
|
264
|
+
'width': width,
|
|
265
|
+
'height': height,
|
|
266
|
+
'size_bytes': len(image_bytes),
|
|
267
|
+
'image_bytes_base64': base64.b64encode(image_bytes).decode('utf-8')
|
|
268
|
+
})
|
|
269
|
+
except Exception as e:
|
|
270
|
+
logger.warning(f"Failed to extract image {img_idx} from page {page_idx + 1}: {e}")
|
|
271
|
+
|
|
272
|
+
raw_content['pages'].append(page_data)
|
|
273
|
+
|
|
274
|
+
doc.close()
|
|
275
|
+
pdf_plumber.close()
|
|
276
|
+
|
|
277
|
+
except Exception as e:
|
|
278
|
+
logger.error(f"Error extracting raw content from PDF: {e}")
|
|
279
|
+
import traceback
|
|
280
|
+
logger.error(traceback.format_exc())
|
|
281
|
+
raise
|
|
282
|
+
|
|
283
|
+
return raw_content
|
|
284
|
+
|
|
285
|
+
def _llm_process_content(self, raw_content: Dict[str, Any],
|
|
286
|
+
extract_tables: bool,
|
|
287
|
+
extract_images: bool,
|
|
288
|
+
extract_entities: bool,
|
|
289
|
+
generate_chunks: bool,
|
|
290
|
+
chunk_strategy: str) -> LLMExtractionResult:
|
|
291
|
+
"""
|
|
292
|
+
Use LLM to process raw content and extract structured information.
|
|
293
|
+
|
|
294
|
+
This sends the raw extracted content to LLM with a carefully crafted prompt
|
|
295
|
+
to extract tables, images, entities, and generate chunks while preserving
|
|
296
|
+
reading order.
|
|
297
|
+
"""
|
|
298
|
+
# Build the prompt for LLM
|
|
299
|
+
prompt = self._build_extraction_prompt(
|
|
300
|
+
raw_content,
|
|
301
|
+
extract_tables=extract_tables,
|
|
302
|
+
extract_images=extract_images,
|
|
303
|
+
extract_entities=extract_entities,
|
|
304
|
+
generate_chunks=generate_chunks,
|
|
305
|
+
chunk_strategy=chunk_strategy
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
logger.info("=" * 80)
|
|
309
|
+
logger.info("Sending extraction request to LLM...")
|
|
310
|
+
logger.info(f"Prompt length: {len(prompt)} characters")
|
|
311
|
+
logger.info(f"Pages to process: {len(raw_content['pages'])}")
|
|
312
|
+
total_tables = sum(len(page.get('tables', [])) for page in raw_content['pages'])
|
|
313
|
+
total_images = sum(len(page.get('images', [])) for page in raw_content['pages'])
|
|
314
|
+
logger.info(f"[EMOJI] Raw extraction found: {total_tables} tables, {total_images} images")
|
|
315
|
+
logger.info(f"[EMOJI] Extract tables: {extract_tables}, Extract images: {extract_images}")
|
|
316
|
+
logger.info(f"[EMOJI] Processing mode: ALL PAGES IN ONE REQUEST (not page-by-page)")
|
|
317
|
+
logger.info(f"Prompt preview (first 2000 chars):\n{prompt[:2000]}")
|
|
318
|
+
print(f"[LLM EXTRACTOR] Processing {len(raw_content['pages'])} pages in ONE request")
|
|
319
|
+
print(f"[LLM EXTRACTOR] Raw tables found: {total_tables}, Raw images found: {total_images}")
|
|
320
|
+
print(f"[LLM EXTRACTOR] Extract tables={extract_tables}, Extract images={extract_images}")
|
|
321
|
+
|
|
322
|
+
# Debug: Show table/image details per page
|
|
323
|
+
for page_data in raw_content['pages']:
|
|
324
|
+
page_num = page_data['page_number']
|
|
325
|
+
page_tables = len(page_data.get('tables', []))
|
|
326
|
+
page_images = len(page_data.get('images', []))
|
|
327
|
+
if page_tables > 0 or page_images > 0:
|
|
328
|
+
print(f"[LLM EXTRACTOR] Page {page_num}: {page_tables} tables, {page_images} images")
|
|
329
|
+
if page_tables > 0:
|
|
330
|
+
for idx, table in enumerate(page_data.get('tables', [])):
|
|
331
|
+
headers = table.get('headers', [])
|
|
332
|
+
rows_count = len(table.get('rows', []))
|
|
333
|
+
print(f" Table {idx+1}: {len(headers)} columns, {rows_count} rows, headers={headers[:3]}")
|
|
334
|
+
if page_images > 0:
|
|
335
|
+
for idx, img in enumerate(page_data.get('images', [])):
|
|
336
|
+
print(f" Image {idx+1}: {img.get('format', '?')} {img.get('width', 0)}x{img.get('height', 0)}")
|
|
337
|
+
|
|
338
|
+
logger.info("=" * 80)
|
|
339
|
+
|
|
340
|
+
# Call LLM
|
|
341
|
+
try:
|
|
342
|
+
print(f"[LLM EXTRACTOR] Calling LLM with model={self.llm_model}, temperature={self.temperature}")
|
|
343
|
+
print(f"[LLM EXTRACTOR] Prompt length: {len(prompt)} chars")
|
|
344
|
+
llm_response = self.llm_provider.generate(
|
|
345
|
+
prompt=prompt,
|
|
346
|
+
model=self.llm_model,
|
|
347
|
+
temperature=self.temperature,
|
|
348
|
+
max_tokens=16000 # Large response needed for structured data
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
# Extract response text from dict if needed
|
|
352
|
+
if isinstance(llm_response, dict):
|
|
353
|
+
response = llm_response.get('response', llm_response.get('text', llm_response.get('content', '')))
|
|
354
|
+
else:
|
|
355
|
+
response = str(llm_response) if llm_response else ''
|
|
356
|
+
|
|
357
|
+
if not response or not response.strip():
|
|
358
|
+
raise ValueError("Empty response from LLM")
|
|
359
|
+
|
|
360
|
+
print(f"[LLM EXTRACTOR] LLM response received: {len(response)} chars")
|
|
361
|
+
print(f"[LLM EXTRACTOR] Response preview (first 500 chars):\n{response[:500]}")
|
|
362
|
+
|
|
363
|
+
# Parse LLM response (should be JSON)
|
|
364
|
+
result = self._parse_llm_response(response)
|
|
365
|
+
|
|
366
|
+
print(f"[LLM EXTRACTOR] Parsed result: {len(result.tables)} tables, {len(result.images)} images")
|
|
367
|
+
if len(result.tables) > 0:
|
|
368
|
+
print(f"[LLM EXTRACTOR] First table: {result.tables[0].headers}")
|
|
369
|
+
if len(result.images) > 0:
|
|
370
|
+
print(f"[LLM EXTRACTOR] First image: {result.images[0].description}")
|
|
371
|
+
|
|
372
|
+
return result
|
|
373
|
+
|
|
374
|
+
except Exception as e:
|
|
375
|
+
logger.error(f"LLM processing failed: {e}")
|
|
376
|
+
import traceback
|
|
377
|
+
logger.error(traceback.format_exc())
|
|
378
|
+
# Fallback to basic extraction
|
|
379
|
+
return self._fallback_extraction(raw_content)
|
|
380
|
+
|
|
381
|
+
def _build_extraction_prompt(self, raw_content: Dict[str, Any],
|
|
382
|
+
extract_tables: bool,
|
|
383
|
+
extract_images: bool,
|
|
384
|
+
extract_entities: bool,
|
|
385
|
+
generate_chunks: bool,
|
|
386
|
+
chunk_strategy: str) -> str:
|
|
387
|
+
"""Build comprehensive prompt for LLM extraction."""
|
|
388
|
+
|
|
389
|
+
# Summarize raw content for prompt (to avoid token limits)
|
|
390
|
+
content_summary = []
|
|
391
|
+
for page_data in raw_content['pages']:
|
|
392
|
+
page_text = "\n".join([block['text'] for block in page_data.get('text_blocks', [])])
|
|
393
|
+
content_summary.append({
|
|
394
|
+
'page': page_data['page_number'],
|
|
395
|
+
'text_preview': page_text[:500] + "..." if len(page_text) > 500 else page_text,
|
|
396
|
+
'text_length': len(page_text),
|
|
397
|
+
'table_count': len(page_data.get('tables', [])),
|
|
398
|
+
'image_count': len(page_data.get('images', []))
|
|
399
|
+
})
|
|
400
|
+
|
|
401
|
+
prompt = f"""You are an expert document analysis AI. Analyze the following PDF document content and extract structured information.
|
|
402
|
+
|
|
403
|
+
# DOCUMENT CONTENT:
|
|
404
|
+
|
|
405
|
+
"""
|
|
406
|
+
|
|
407
|
+
# Add text content (first 5000 chars per page to avoid token limits)
|
|
408
|
+
for page_data in raw_content['pages']:
|
|
409
|
+
page_text = "\n".join([block['text'] for block in page_data.get('text_blocks', [])])
|
|
410
|
+
# Truncate if too long
|
|
411
|
+
if len(page_text) > 5000:
|
|
412
|
+
page_text = page_text[:5000] + "... [truncated]"
|
|
413
|
+
|
|
414
|
+
prompt += f"""
|
|
415
|
+
## PAGE {page_data['page_number']}:
|
|
416
|
+
|
|
417
|
+
{page_text}
|
|
418
|
+
|
|
419
|
+
"""
|
|
420
|
+
|
|
421
|
+
# Add table extraction instructions - LLM should extract tables directly from text
|
|
422
|
+
if extract_tables:
|
|
423
|
+
prompt += """
|
|
424
|
+
# TABLE EXTRACTION:
|
|
425
|
+
|
|
426
|
+
IMPORTANT: You must identify and extract ALL tables from the document text above.
|
|
427
|
+
|
|
428
|
+
Look for:
|
|
429
|
+
- Tabular data with rows and columns
|
|
430
|
+
- Headers followed by data rows
|
|
431
|
+
- Financial tables, data tables, comparison tables
|
|
432
|
+
- Any structured data in table format
|
|
433
|
+
|
|
434
|
+
For each table you find:
|
|
435
|
+
1. Identify the headers (column names)
|
|
436
|
+
2. Extract ALL data rows
|
|
437
|
+
3. Preserve the exact structure and data
|
|
438
|
+
4. Include the page number where the table appears
|
|
439
|
+
|
|
440
|
+
IMPORTANT: Extract tables directly from the text content provided above. Do not rely on any pre-extracted table data.
|
|
441
|
+
Even if the text appears unstructured, identify tabular patterns and extract them as tables.
|
|
442
|
+
|
|
443
|
+
"""
|
|
444
|
+
|
|
445
|
+
# Add image information
|
|
446
|
+
if extract_images:
|
|
447
|
+
prompt += """
|
|
448
|
+
# IMAGES IN DOCUMENT:
|
|
449
|
+
|
|
450
|
+
IMPORTANT: Extract ALL images found below. For each image, provide a description based on the document context.
|
|
451
|
+
|
|
452
|
+
"""
|
|
453
|
+
image_count = 0
|
|
454
|
+
for page_data in raw_content['pages']:
|
|
455
|
+
for image in page_data.get('images', []):
|
|
456
|
+
image_count += 1
|
|
457
|
+
prompt += f"""
|
|
458
|
+
### Image {image['image_index']} (Page {page_data['page_number']}):
|
|
459
|
+
|
|
460
|
+
Format: {image.get('format', 'UNKNOWN')}
|
|
461
|
+
Width: {image.get('width', 0)} pixels
|
|
462
|
+
Height: {image.get('height', 0)} pixels
|
|
463
|
+
Size: {image.get('size_bytes', 0)} bytes
|
|
464
|
+
"""
|
|
465
|
+
# Note: Image base64 data is available but too large for prompt
|
|
466
|
+
# LLM should extract from context or describe what it sees in text
|
|
467
|
+
prompt += "Note: Image data is available. Extract description from document context.\n\n"
|
|
468
|
+
|
|
469
|
+
if image_count == 0:
|
|
470
|
+
prompt += "No images found in raw extraction.\n\n"
|
|
471
|
+
else:
|
|
472
|
+
prompt += f"\nTOTAL: {image_count} images found. Extract ALL of them in your JSON response.\n\n"
|
|
473
|
+
|
|
474
|
+
prompt += f"""
|
|
475
|
+
|
|
476
|
+
# EXTRACTION TASK:
|
|
477
|
+
|
|
478
|
+
Extract and structure the following information from the document:
|
|
479
|
+
|
|
480
|
+
1. **Text Content**: Preserve natural reading order (left-to-right, top-to-bottom, column-by-column)
|
|
481
|
+
2. **Tables**: CRITICAL - Identify and extract ALL tables directly from the text. Look for tabular patterns, rows/columns, headers and data. Extract complete table structures with all rows and columns. Even if text appears unstructured, identify and extract any tabular data patterns.
|
|
482
|
+
3. **Images**: Extract image metadata (for images, I'll provide base64 data if needed)
|
|
483
|
+
4. **Named Entities**: Extract all entities (PERSON, ORGANIZATION, LOCATION, DATE, MONEY, etc.)
|
|
484
|
+
5. **Semantic Chunks**: Create meaningful chunks using {chunk_strategy} strategy
|
|
485
|
+
|
|
486
|
+
# OUTPUT FORMAT:
|
|
487
|
+
|
|
488
|
+
Return a JSON object with this exact structure:
|
|
489
|
+
|
|
490
|
+
{{
|
|
491
|
+
"text_content": "Full document text in proper reading order",
|
|
492
|
+
"tables": [
|
|
493
|
+
{{
|
|
494
|
+
"table_index": 1,
|
|
495
|
+
"page_number": 1,
|
|
496
|
+
"headers": ["Column1", "Column2"],
|
|
497
|
+
"rows": [["Row1Col1", "Row1Col2"], ["Row2Col1", "Row2Col2"]],
|
|
498
|
+
"title": "Table Title (if any)",
|
|
499
|
+
"caption": "Table Caption (if any)"
|
|
500
|
+
}}
|
|
501
|
+
],
|
|
502
|
+
"images": [
|
|
503
|
+
{{
|
|
504
|
+
"image_index": 1,
|
|
505
|
+
"page_number": 1,
|
|
506
|
+
"description": "Description of what the image shows",
|
|
507
|
+
"width": 800,
|
|
508
|
+
"height": 600,
|
|
509
|
+
"format": "PNG"
|
|
510
|
+
}}
|
|
511
|
+
],
|
|
512
|
+
"entities": [
|
|
513
|
+
{{
|
|
514
|
+
"entity_type": "ORGANIZATION",
|
|
515
|
+
"entity_name": "TCS",
|
|
516
|
+
"canonical_name": "Tata Consultancy Services",
|
|
517
|
+
"context": "Surrounding text where entity appears"
|
|
518
|
+
}}
|
|
519
|
+
],
|
|
520
|
+
"chunks": [
|
|
521
|
+
{{
|
|
522
|
+
"chunk_index": 1,
|
|
523
|
+
"content": "Chunk text content",
|
|
524
|
+
"chunk_type": "paragraph",
|
|
525
|
+
"page_number": 1,
|
|
526
|
+
"entities": ["entity_name1", "entity_name2"]
|
|
527
|
+
}}
|
|
528
|
+
],
|
|
529
|
+
"metadata": {{
|
|
530
|
+
"reading_order_preserved": true,
|
|
531
|
+
"extraction_method": "llm",
|
|
532
|
+
"model": "{self.llm_model}"
|
|
533
|
+
}}
|
|
534
|
+
}}
|
|
535
|
+
|
|
536
|
+
# IMPORTANT INSTRUCTIONS:
|
|
537
|
+
|
|
538
|
+
1. **Reading Order**: When reconstructing text, read column-by-column (left column completely, then right column)
|
|
539
|
+
2. **Tables**: Preserve exact table structure - don't modify data
|
|
540
|
+
3. **Entities**: Extract all proper nouns, organizations, locations, dates, financial figures
|
|
541
|
+
4. **Chunks**: Create semantic chunks that preserve topic boundaries - each chunk should be a complete thought
|
|
542
|
+
5. **Quality**: Ensure accuracy - this data will be used for search and knowledge graph construction
|
|
543
|
+
|
|
544
|
+
Now extract the information and return ONLY valid JSON (no markdown, no code blocks):
|
|
545
|
+
"""
|
|
546
|
+
|
|
547
|
+
return prompt
|
|
548
|
+
|
|
549
|
+
def _parse_llm_response(self, response: str) -> LLMExtractionResult:
|
|
550
|
+
"""Parse LLM JSON response into structured result."""
|
|
551
|
+
try:
|
|
552
|
+
# Clean response - remove markdown code blocks if present
|
|
553
|
+
cleaned_response = response.strip()
|
|
554
|
+
if cleaned_response.startswith("```json"):
|
|
555
|
+
cleaned_response = cleaned_response[7:]
|
|
556
|
+
if cleaned_response.startswith("```"):
|
|
557
|
+
cleaned_response = cleaned_response[3:]
|
|
558
|
+
if cleaned_response.endswith("```"):
|
|
559
|
+
cleaned_response = cleaned_response[:-3]
|
|
560
|
+
cleaned_response = cleaned_response.strip()
|
|
561
|
+
|
|
562
|
+
# Parse JSON
|
|
563
|
+
data = json.loads(cleaned_response)
|
|
564
|
+
|
|
565
|
+
# Convert to structured objects
|
|
566
|
+
tables = [ExtractedTable(**t) for t in data.get('tables', [])]
|
|
567
|
+
images = [ExtractedImage(**img) for img in data.get('images', [])]
|
|
568
|
+
entities = [ExtractedEntity(**e) for e in data.get('entities', [])]
|
|
569
|
+
chunks = [DocumentChunk(**c) for c in data.get('chunks', [])]
|
|
570
|
+
|
|
571
|
+
result = LLMExtractionResult(
|
|
572
|
+
text_content=data.get('text_content', ''),
|
|
573
|
+
tables=tables,
|
|
574
|
+
images=images,
|
|
575
|
+
entities=entities,
|
|
576
|
+
chunks=chunks,
|
|
577
|
+
metadata=data.get('metadata', {}),
|
|
578
|
+
reading_order_preserved=data.get('metadata', {}).get('reading_order_preserved', True)
|
|
579
|
+
)
|
|
580
|
+
|
|
581
|
+
return result
|
|
582
|
+
|
|
583
|
+
except json.JSONDecodeError as e:
|
|
584
|
+
logger.error(f"Failed to parse LLM JSON response: {e}")
|
|
585
|
+
logger.error(f"Response preview: {response[:500]}")
|
|
586
|
+
raise ValueError(f"Invalid JSON response from LLM: {e}")
|
|
587
|
+
except Exception as e:
|
|
588
|
+
logger.error(f"Error parsing LLM response: {e}")
|
|
589
|
+
raise
|
|
590
|
+
|
|
591
|
+
def _fallback_extraction(self, raw_content: Dict[str, Any]) -> LLMExtractionResult:
|
|
592
|
+
"""Fallback extraction if LLM fails - basic text extraction."""
|
|
593
|
+
logger.warning("Using fallback extraction (LLM failed)")
|
|
594
|
+
|
|
595
|
+
text_content = []
|
|
596
|
+
for page_data in raw_content['pages']:
|
|
597
|
+
page_text = "\n".join([block['text'] for block in page_data.get('text_blocks', [])])
|
|
598
|
+
text_content.append(f"Page {page_data['page_number']}:\n{page_text}")
|
|
599
|
+
|
|
600
|
+
return LLMExtractionResult(
|
|
601
|
+
text_content="\n\n".join(text_content),
|
|
602
|
+
tables=[],
|
|
603
|
+
images=[],
|
|
604
|
+
entities=[],
|
|
605
|
+
chunks=[],
|
|
606
|
+
metadata={'extraction_method': 'fallback', 'error': 'LLM extraction failed'},
|
|
607
|
+
reading_order_preserved=False
|
|
608
|
+
)
|
|
609
|
+
|
|
610
|
+
|