osintengine 1.0.3__tar.gz → 1.0.4__tar.gz

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.
Files changed (115) hide show
  1. {osintengine-1.0.3 → osintengine-1.0.4}/PKG-INFO +1 -1
  2. {osintengine-1.0.3 → osintengine-1.0.4}/pyproject.toml +1 -1
  3. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/__init__.py +1 -1
  4. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/orchestration/engine.py +3 -1
  5. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/orchestration/synthesis.py +28 -20
  6. {osintengine-1.0.3 → osintengine-1.0.4}/.env.example +0 -0
  7. {osintengine-1.0.3 → osintengine-1.0.4}/LICENSE +0 -0
  8. {osintengine-1.0.3 → osintengine-1.0.4}/MANIFEST.in +0 -0
  9. {osintengine-1.0.3 → osintengine-1.0.4}/README.md +0 -0
  10. {osintengine-1.0.3 → osintengine-1.0.4}/SELF_HOSTING.md +0 -0
  11. {osintengine-1.0.3 → osintengine-1.0.4}/WATSON_ARCHITECTURE.md +0 -0
  12. {osintengine-1.0.3 → osintengine-1.0.4}/deploy.sh +0 -0
  13. {osintengine-1.0.3 → osintengine-1.0.4}/osintengine.egg-info/SOURCES.txt +0 -0
  14. {osintengine-1.0.3 → osintengine-1.0.4}/requirements.txt +0 -0
  15. {osintengine-1.0.3 → osintengine-1.0.4}/setup.cfg +0 -0
  16. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/agent/__init__.py +0 -0
  17. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/agents/__init__.py +0 -0
  18. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/agents/protocol.py +0 -0
  19. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/auth/__init__.py +0 -0
  20. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/auth/store.py +0 -0
  21. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/conversation.py +0 -0
  22. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/core/__init__.py +0 -0
  23. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/core/models.py +0 -0
  24. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/ethics.py +0 -0
  25. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/exports.py +0 -0
  26. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/graph/__init__.py +0 -0
  27. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/graph/entities.py +0 -0
  28. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/graph/graph.py +0 -0
  29. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/graph/osint_framework.py +0 -0
  30. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/graph/relationships.py +0 -0
  31. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/graph/transforms.py +0 -0
  32. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/infra/__init__.py +0 -0
  33. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/infra/cache.py +0 -0
  34. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/infra/ratelimit.py +0 -0
  35. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/infra/resilience.py +0 -0
  36. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/infra/retry.py +0 -0
  37. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/metrics.py +0 -0
  38. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/opsec/__init__.py +0 -0
  39. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/orchestration/__init__.py +0 -0
  40. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/orchestration/executor.py +0 -0
  41. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/orchestration/intent.py +0 -0
  42. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/orchestration/intent_classifier.py +0 -0
  43. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/orchestration/llm_config.py +0 -0
  44. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/orchestration/resolution.py +0 -0
  45. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/orchestration/scraper.py +0 -0
  46. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/orchestration/target_profile.py +0 -0
  47. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/persistence/__init__.py +0 -0
  48. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/persistence/models.py +0 -0
  49. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/persistence/store.py +0 -0
  50. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/pipeline/__init__.py +0 -0
  51. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/pipeline/pre_synthesis.py +0 -0
  52. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/search.py +0 -0
  53. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/serializers/stix.py +0 -0
  54. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/__init__.py +0 -0
  55. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/base.py +0 -0
  56. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/blockchain.py +0 -0
  57. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/captcha.py +0 -0
  58. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/conflict.py +0 -0
  59. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/corporate.py +0 -0
  60. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/darkweb.py +0 -0
  61. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/geolocation.py +0 -0
  62. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/image_video.py +0 -0
  63. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/marinetraffic.py +0 -0
  64. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/people.py +0 -0
  65. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/registry.py +0 -0
  66. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/satellite.py +0 -0
  67. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/scraper.py +0 -0
  68. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/shodan.py +0 -0
  69. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/social_media.py +0 -0
  70. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/websites.py +0 -0
  71. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/tools/wikidata.py +0 -0
  72. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/utils/__init__.py +0 -0
  73. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/utils/helpers.py +0 -0
  74. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/utils/http.py +0 -0
  75. {osintengine-1.0.3 → osintengine-1.0.4}/src/watson/verification/__init__.py +0 -0
  76. {osintengine-1.0.3 → osintengine-1.0.4}/tests/conftest.py +0 -0
  77. {osintengine-1.0.3 → osintengine-1.0.4}/tests/test_infra.py +0 -0
  78. {osintengine-1.0.3 → osintengine-1.0.4}/tests/test_integration.py +0 -0
  79. {osintengine-1.0.3 → osintengine-1.0.4}/tests/test_persistence.py +0 -0
  80. {osintengine-1.0.3 → osintengine-1.0.4}/tests/test_resolution.py +0 -0
  81. {osintengine-1.0.3 → osintengine-1.0.4}/tests/test_synthesis.py +0 -0
  82. {osintengine-1.0.3 → osintengine-1.0.4}/watson/__init__.py +0 -0
  83. {osintengine-1.0.3 → osintengine-1.0.4}/watson/agents/__init__.py +0 -0
  84. {osintengine-1.0.3 → osintengine-1.0.4}/watson/agents/base.py +0 -0
  85. {osintengine-1.0.3 → osintengine-1.0.4}/watson/agents/direct.py +0 -0
  86. {osintengine-1.0.3 → osintengine-1.0.4}/watson/agents/hermes.py +0 -0
  87. {osintengine-1.0.3 → osintengine-1.0.4}/watson/agents/hermes_mcp.py +0 -0
  88. {osintengine-1.0.3 → osintengine-1.0.4}/watson/api_keys.py +0 -0
  89. {osintengine-1.0.3 → osintengine-1.0.4}/watson/browser_scraper.py +0 -0
  90. {osintengine-1.0.3 → osintengine-1.0.4}/watson/cli.py +0 -0
  91. {osintengine-1.0.3 → osintengine-1.0.4}/watson/crossref.py +0 -0
  92. {osintengine-1.0.3 → osintengine-1.0.4}/watson/ethics.py +0 -0
  93. {osintengine-1.0.3 → osintengine-1.0.4}/watson/graph.py +0 -0
  94. {osintengine-1.0.3 → osintengine-1.0.4}/watson/mcp_server.py +0 -0
  95. {osintengine-1.0.3 → osintengine-1.0.4}/watson/memory.py +0 -0
  96. {osintengine-1.0.3 → osintengine-1.0.4}/watson/neo4j_graph.py +0 -0
  97. {osintengine-1.0.3 → osintengine-1.0.4}/watson/opsec/__init__.py +0 -0
  98. {osintengine-1.0.3 → osintengine-1.0.4}/watson/reporter.py +0 -0
  99. {osintengine-1.0.3 → osintengine-1.0.4}/watson/scheduler.py +0 -0
  100. {osintengine-1.0.3 → osintengine-1.0.4}/watson/serializers/stix.py +0 -0
  101. {osintengine-1.0.3 → osintengine-1.0.4}/watson/terminal.py +0 -0
  102. {osintengine-1.0.3 → osintengine-1.0.4}/watson/toolkit.py +0 -0
  103. {osintengine-1.0.3 → osintengine-1.0.4}/watson/toolkit_api.py +0 -0
  104. {osintengine-1.0.3 → osintengine-1.0.4}/watson/toolkit_automation.py +0 -0
  105. {osintengine-1.0.3 → osintengine-1.0.4}/watson/toolkit_registry.py +0 -0
  106. {osintengine-1.0.3 → osintengine-1.0.4}/watson/verification/__init__.py +0 -0
  107. {osintengine-1.0.3 → osintengine-1.0.4}/watson/web/__init__.py +0 -0
  108. {osintengine-1.0.3 → osintengine-1.0.4}/watson/web/app.py +0 -0
  109. {osintengine-1.0.3 → osintengine-1.0.4}/watson/web/middleware.py +0 -0
  110. {osintengine-1.0.3 → osintengine-1.0.4}/watson/web/static/assets/index-B7hPOc0z.js +0 -0
  111. {osintengine-1.0.3 → osintengine-1.0.4}/watson/web/static/assets/index-CJ6FP8Mp.css +0 -0
  112. {osintengine-1.0.3 → osintengine-1.0.4}/watson/web/static/assets/watson-logo-Dk9tawHb.png +0 -0
  113. {osintengine-1.0.3 → osintengine-1.0.4}/watson/web/static/index.html +0 -0
  114. {osintengine-1.0.3 → osintengine-1.0.4}/watson/web/templates/chat.html +0 -0
  115. {osintengine-1.0.3 → osintengine-1.0.4}/watson/web/templates/investigation-map.html +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: osintengine
3
- Version: 1.0.3
3
+ Version: 1.0.4
4
4
  Summary: The OSINT investigation engine — 7-phase pipeline, persistent knowledge graph, community intelligence
5
5
  Author-email: Lorenzo Baron <baron.lorenzo99@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "osintengine"
3
- version = "1.0.3"
3
+ version = "1.0.4"
4
4
  description = "The OSINT investigation engine — 7-phase pipeline, persistent knowledge graph, community intelligence"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -7,4 +7,4 @@ must be the truth." — Sherlock Holmes
7
7
  Autonomous open-source intelligence with 338 Bellingcat tools.
8
8
  Knowledge graph, lead tracking, recursive investigation.
9
9
  """
10
- __version__ = "1.0.3"
10
+ __version__ = "1.0.4"
@@ -3616,7 +3616,9 @@ Examples:
3616
3616
  except Exception as e:
3617
3617
  logger.warning("resolution_failed: %s", e)
3618
3618
 
3619
- # Synthesis
3619
+ # Synthesis — filter noise before feeding to LLM
3620
+ findings = self._filter_quality(findings, query=query)
3621
+
3620
3622
  try:
3621
3623
  from .synthesis import synthesize_brief
3622
3624
  from .llm_config import call_llm
@@ -560,37 +560,45 @@ def _fallback_brief(query: str, findings: list) -> dict:
560
560
  "Financial": ["revenue", "profit", "loss", "billion", "million", "funding", "valuation",
561
561
  "stock", "share", "investor", "ipo", "acquisition"],
562
562
  "Crime / Investigation": ["criminal", "arrest", "prison", "jail", "fraud", "money laundering",
563
- "investigation", "probe", "allegation", "misconduct"],
564
- "Infrastructure / Technical": ["dns", "ip address", "nameserver", "hosting", "cdn",
565
- "subdomain", "resolves_to", "mx record"],
563
+ "investigation", "probe", "allegation", "misconduct", "wanted", "fugitive",
564
+ "fbi", "hacker", "cyber"],
566
565
  }
567
566
  themes = []
568
567
  all_text = " ".join(titles + [getattr(f, "description", "") or "" for f in findings]).lower()
569
568
  for theme, keywords in theme_keywords.items():
570
569
  matches = [kw for kw in keywords if kw in all_text]
571
570
  if matches:
572
- # Extract a relevant finding snippet
571
+ # Find the best finding for this theme — prefer ones with real descriptions
572
+ best_summary = f"Evidence of {matches[0]} found across multiple sources."
573
+ best_source = ""
573
574
  for f in findings:
574
- desc = (getattr(f, "description", "") or "").lower()
575
+ desc = (getattr(f, "description", "") or "")
575
576
  title_l = (getattr(f, "title", "") or "").lower()
576
577
  for kw in matches:
577
- if kw in title_l or kw in desc:
578
- themes.append({
579
- "theme": theme,
580
- "severity": "HIGH" if theme.startswith("Crime") else "MEDIUM",
581
- "summary": getattr(f, "title", "")[:200] or f"Evidence of {kw} found",
582
- "source_titles": [getattr(f, "title", "")[:100]],
583
- })
578
+ if kw in title_l or kw in desc.lower():
579
+ # Use the description as summary (actual intelligence, not just title)
580
+ if desc and len(desc) > 20:
581
+ best_summary = desc[:300]
582
+ best_source = getattr(f, "source_url", "") or ""
584
583
  break
585
- if any(t["theme"] == theme for t in themes):
584
+ if best_source:
586
585
  break
587
- else:
588
- themes.append({
589
- "theme": theme,
590
- "severity": "MEDIUM",
591
- "summary": f"Keywords detected: {', '.join(matches[:4])}",
592
- "source_titles": [],
593
- })
586
+ themes.append({
587
+ "theme": theme,
588
+ "severity": "HIGH" if theme.startswith("Crime") else "MEDIUM",
589
+ "summary": best_summary,
590
+ "source_titles": [best_source] if best_source else [],
591
+ })
592
+
593
+ # Deduplicate themes — same summary shouldn't appear for multiple themes
594
+ seen_summaries = set()
595
+ deduped_themes = []
596
+ for t in themes:
597
+ key = t["summary"][:50]
598
+ if key not in seen_summaries:
599
+ seen_summaries.add(key)
600
+ deduped_themes.append(t)
601
+ themes = deduped_themes[:5]
594
602
 
595
603
  # Extract timeline events from findings (dates in titles/descriptions)
596
604
  timeline_events: list[dict] = []
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes