Commit Graph
21 Commits
Author SHA1 Message Date
KaifAhmad1andZohaib Hassan e7c9f6e7f3 fix(tests): restore sys.modules after mock injection in test_retry_logic
test_retry_logic.py injected sys.modules["openai"] = MagicMock() at module
level so providers.py could be imported without the real openai package.
Those mocks were never restored, leaving openai (and spacy, instructor etc.)
as MagicMock objects for the entire test session. This caused
test_pr482_deepseek_openai tests to receive a MagicMock when importing
openai.OpenAI, making MagicMock(spec=OpenAI) raise InvalidSpecError.

Fix: save original sys.modules entries before injection and restore them
immediately after the semantica imports that needed the mocks complete.
The mock objects remain bound inside the already-imported provider module,
so test_retry_logic tests are unaffected; other test modules now see the
real packages again.

Co-authored-by: Zohaib Hassan <zohaib179949@gmail.com>
Co-authored-by: KaifAhmad1 <kaifahmad087@gmail.com>
2026-05-05 14:21:36 +05:30
KaifAhmad1andZohaib Hassan 24e327d161 fix(tests): add from __future__ import annotations for Py3.8 compatibility
subprocess.CompletedProcess[str] as a return annotation is not subscriptable
at runtime on Python 3.8, causing test collection to abort before any tests
run. Adding PEP 563 deferred evaluation makes all annotations strings at
import time, restoring 3.8 compatibility without changing behaviour on 3.9+.

Co-authored-by: Zohaib Hassan <zohaib179949@gmail.com>
Co-authored-by: KaifAhmad1 <kaifahmad087@gmail.com>
2026-05-05 13:40:11 +05:30
Zohaib Hassnain e1b1e63541 fix(semantic_extract): break extractor import cycle 2026-05-05 02:26:57 +05:00
983f5301e8 fix(providers): switch DeepSeekProvider to OpenAI SDK + fix base_url and verbose_mode (closes #482)
- Replace deepseek.Client with openai.OpenAI(base_url="https://api.deepseek.com/v1")
  in DeepSeekProvider._init_client(); the deepseek PyPI package has no Client class
- Add self.base_url = "https://api.deepseek.com/v1" to DeepSeekProvider.__init__()
  (missing from original PR; caused AttributeError on every instantiation)
- Fix verbose_mode NameError in BaseProvider.generate_typed() instructor path
- Update pyproject.toml: llm-deepseek extra now declares openai>=1.0.0
- Update _init_client warning message to reference openai library
- Add 19 tests in tests/semantic_extract/test_pr482_deepseek_openai.py
- Update CHANGELOG.md

Co-authored-by: liling <liling@users.noreply.github.com>
Co-authored-by: KaifAhmad1 <mohammadk78600@gmail.com>
2026-04-19 20:07:44 +05:30
KaifAhmad1andClaude Sonnet 4.6 b9af181625 feat(semantic-extract): temporal metadata extraction from text (#400)
- Add `extract_temporal_bounds: bool = False` to `extract_relations_llm()`.
  When True the LLM prompt is extended with a calibrated confidence scale
  and four few-shot examples; each returned Relation gains valid_from,
  valid_until, temporal_confidence, and temporal_source_text in metadata.
  Low confidence (<0.5) with non-null dates logs a WARNING. Default False
  preserves 100% backward compatibility.

- Add `RelationWithTemporalOut` / `RelationsWithTemporalResponse` Pydantic
  schemas so the four temporal fields are captured from structured LLM
  output (separate from RelationOut which uses extra="ignore").

- New `semantica/kg/temporal_normalizer.py` — `TemporalNormalizer` class
  (zero LLM calls, pure regex + dateutil arithmetic):
    * normalize(value) → (start, end) UTC datetimes or None
    * Resolution order: ISO 8601 → partial dates (year/month/Q) →
      ambiguity detection → domain phrase map → relative phrases
    * normalize_phrase(phrase) → metadata dict or None
    * Default phrase map covers 13 domains: General, Policy, Healthcare,
      Drug Discovery, Cybersecurity, Supply Chain, Finance, Energy
    * TemporalAmbiguityWarning for DD/MM/YYYY-style ambiguous inputs
    * Custom phrase_map at construction (merged over defaults)

- Add `TemporalAmbiguityWarning(UserWarning)` to exceptions.py.
- Export `TemporalNormalizer` from `semantica/kg/__init__.py`.
- Propagate `extract_temporal_bounds` through `_extract_relations_chunked`
  and add flag to cache key to prevent cross-mode cache pollution.

- 53 new tests in tests/semantic_extract/test_temporal_extraction.py;
  zero real LLM calls, suite runs in ~3.5s. 873 existing tests unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 21:42:57 +05:30
KaifAhmad1andClaude Sonnet 4.6 19665b9db2 fix(semantic-extract): pass base_url as host when initialising OllamaProvider client
Closes #408

Previously `_init_client` assigned the raw `ollama` module to
`self.client`, so the `base_url` parameter was silently ignored and
every request hit the default localhost:11434. Now an `ollama.Client`
instance is created with `host=self.base_url`, so remote Ollama servers
are reachable.

Three regression tests added to prevent recurrence:
- default base_url is forwarded as host
- custom base_url (e.g. http://192.168.1.3:11434) is forwarded as host
- self.client is never the raw module

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 19:36:22 +05:30
KaifAhmad1andClaude Sonnet 4.6 78c52eb099 fix: resolve 0.3.0 bugs and add comprehensive real-world tests
- Export ProvenanceTracker from semantica/kg/__init__.py (was missing)
- Remove duplicate relation creation in _parse_relation_result (legacy orphaned block)
- Add extraction_method param to _parse_relation_result; pass 'llm_typed' from typed path
- Clear _result_cache in test setUp to prevent cross-test cache pollution
- Add tests/test_030_realworld_comprehensive.py: 85 real-world tests covering all
  0.3.0-alpha/beta features (ContextGraph, decision tracking, KG algorithms,
  PolicyEngine, dedup v2, RDF export, Reasoner, Pipeline, ProvenanceTracker,
  semantic extract, multi-hop investment chains, healthcare E2E)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 01:02:39 +05:30
Mohd Kaif 5555c2afa5 Merge branch 'main' into reasoning 2026-03-07 02:27:04 +05:30
KaifAhmad1andClaude Sonnet 4.6 246bcc96cd fix: resolve multi-founder LLM extraction and Reasoner inference bugs (#354)
Bug 1 — _parse_relation_result (methods.py):
Relations whose subject/object weren't in the pre-extracted NER list were
silently dropped because match_entity() returned None and the old code
gated on `if subject_entity and object_entity`. Now unmatched names
produce a synthetic UNKNOWN Entity so every LLM-returned relation is
preserved (all three Apple co-founders are now returned).

Bug 2 — _match_pattern (reasoner.py):
Rewrote the regex builder to split on ?var placeholders first, then
apply re.escape() only to the surrounding literal segments. The old
approach (escape-then-sub) left edge cases where pre-bound variables
and multi-word values with spaces could fail to unify. The new
implementation also handles repeated variables via backreferences and
uses non-greedy .+? to avoid over-consuming literal separators.

Closes #354

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 02:23:27 +05:30
Steffen John 78664ec5f6 test: add tests for temperature=None behavior
Verify that temperature parameter is omitted from API calls when None,
allowing models to use their defaults. Tests cover OpenAI, Groq, Gemini,
Ollama, and DeepSeek providers.
2026-01-31 22:16:09 +01:00
KaifAhmad1 bc55dcc57a Fix stuck retries in extraction and enable configurable retry limit. Resolves #207 2026-01-25 21:27:03 +05:30
KaifAhmad1 c7814616a9 Improve semantic_extract performance and add Groq LLM smoke tests 2026-01-14 17:11:26 +05:30
KaifAhmad1 d2e599bcb0 [SECURITY] Enhance caching security by excluding sensitive keys and using SHA-256 2026-01-14 00:22:41 +05:30
KaifAhmad1 dd7fcd3ddb [FEATURE] Performance Bottlenecks and Scaling Limitations in semantic_extract #186
- Implemented high-throughput parallel batch processing across all core extractors (NERExtractor, RelationExtractor, TripletExtractor, EventDetector, SemanticNetworkExtractor) using ThreadPoolExecutor.

- Added max_workers configuration parameter (default: 1) to all extractor extract() methods.

- Implemented parallel processing for large document chunking in _extract_entities_chunked and _extract_relations_chunked.

- Enhanced ProgressTracker to be thread-safe.

- Optimized setUpClass in tests to reduce Groq LLM initialization overhead.

- Updated documentation and usage examples.
2026-01-14 00:11:30 +05:30
KaifAhmad1 8c3f7f1f0a fix(semantic-extract): resolve incomplete output #176, relax constraints, and add Groq support 2026-01-12 17:15:21 +05:30
KaifAhmad1 f338b66274 feat: Add provenance metadata and robust fallback chains to semantic extraction
- Implemented ML/LLM -> Pattern -> Last Resort fallback chains for NER, Relation, and Triplet extractors to prevent empty results.
- Added provenance metadata (batch_index, document_id) to all extraction schemas (Entity, Relation, Triplet, etc.).
- Unified batch processing API with progress tracking across all extractors.
- Updated documentation (module usage and reference docs) to reflect new features.
- Added robustness and batch provenance tests.
2026-01-10 20:43:09 +05:30
KaifAhmad1 a5c531fd29 Fix semantic extraction empty returns, schema validation, and update docs 2026-01-09 18:39:09 +05:30
KaifAhmad1 58707ff721 fix(kg): resolve 'unhashable type: Entity' in GraphAnalyzer #159
- Robust ID extraction in CentralityCalculator, CommunityDetector, and ConnectivityAnalyzer
- Support for direct Entity objects and dictionaries as node identifiers
- Improved Entity hashability in utils/types.py
- Added integration test to verify fix and prevent regression
2026-01-08 17:23:31 +05:30
KaifAhmad1 e3b53998c3 Fix dependency issues, align GraphRAG notebook, and update changelog 2026-01-07 19:00:30 +05:30
KaifAhmad1 4fdc483935 Refactor terminology: Triple -> Triplet across codebase, docs, and notebooks 2025-12-15 16:09:20 +05:30
KaifAhmad1 5d5928badf feat: enhance kg module with tests, conflict resolution placeholders, and doc updates 2025-12-11 15:21:39 +05:30