Documents the removal of the overwritten regex pattern and unreachable
return statement in _match_pattern, and the surfacing of regex errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Package & distribution
- pyproject.toml: add integrations* to packages.find include so pip
install semantica[agno] ships the integration
context_store.py
- upsert_memory(): run NERExtractor after store() to index entities
into the ContextGraph
- delete_memory() / drop_table() / clear(): call AgentContext.forget()
to propagate deletions to vector/graph storage
- find_precedents(): pass limit parameter to find_precedents_advanced()
- retrieve(): pass limit as max_results to AgentContext.retrieve()
- add get_context_for_prompt() for automatic system-prompt injection
knowledge_graph.py
- __init__: wire graph_builder.graph_store = self._graph so build()
persists into the ContextGraph
- add internal AgentContext for vector retrieval (shared ContextGraph)
- search(): use AgentContext.retrieve() for vector similarity; keyword
scoring as fallback
- _ingest_text(): add paragraph-level chunking before NER/relation
extraction (parse → split → NER → relation extract → graph build)
- get_graph_context(): return structured subgraph with edge types via
ContextGraph.get_neighbors()
- load_urls(): validate scheme (http/https only) to prevent SSRF
decision_kit.py
- check_policy(): replace broken PolicyEngine.check_compliance() call
with inline _eval_rule() that evaluates simple field-op-value rules;
return compliant=False (not True) on failure — closes security bug
kg_toolkit.py
- add_to_graph(): fix add_node(node_id=, node_type=) and
add_edge(source_id=, target_id=, edge_type=) to match real API
- query_graph(): use find_nodes() (no label param) + keyword filter
- find_related(): use get_neighbors(node_id=) returning List[Dict]
- infer_facts() / export_subgraph(): use find_nodes() public API
instead of private _nodes dict
shared_context.py
- _AgentScopedStore: store shared context as self._context (not
self._ctx) so all inherited AgnoContextStore methods work correctly
tests/integrations/agno/test_kg_toolkit.py
- _FakeGraph: rewrite to match real ContextGraph signatures —
find_nodes(node_type=), add_node(node_id, node_type, **),
add_edge(source_id, target_id, edge_type, **),
get_neighbors(node_id, hops=1, ...) returning List[Dict]
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Register 'integration' pytest mark in pyproject.toml to eliminate
PytestUnknownMarkWarning across the test suite
- Add -m "not integration" and --ignore for external-service tests,
notebook tests, comprehensive real-world tests, and API-key-dependent
tests (Groq, Novita, Snowflake, Neptune, HF deepdive)
- Keeps fast unit tests: context, kg, semantic_extract, reasoning,
pipeline, export, deduplication, parse, normalize, utils, provenance
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace '*.md' with '**/*.md' in paths-ignore across ci.yml,
benchmark.yml, and security-scan.yml — '*.md' only matches root-level
markdown; '**/*.md' covers all subdirectories (cookbook/, docs/, etc.)
- Add cache: 'pip' to setup-python in ci.yml to avoid re-downloading
heavy packages (torch, spacy, faiss) on every run
- Update security-scan PR comment text to accurately reflect that it
skips doc/markdown-only PRs, not "every PR"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When centrality_calculator falls back to basic implementation on a mocked
networkx call, measure_data['centrality'].get() can return a MagicMock.
MagicMock silently supports __mul__ and __add__, so the arithmetic on
influence_score produces a MagicMock instead of raising, causing the
isinstance(influence_score, (int, float)) assertion to fail in tests.
Guard each centrality value with isinstance(val, (int, float)) and default
to 0.0 for any non-numeric value before storing it.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
semantica.semantic_extract.models does not exist; Entity is defined in
ner_extractor.py and exported from semantica.semantic_extract directly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Method signature 'def _extract_metadata(self, prs: Presentation)' references
Presentation at class-definition time (evaluated on import), causing NameError
since Presentation is no longer imported at module level. Replace with Any.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
python-pptx is not in [dev] extras so it's absent in CI, causing
ModuleNotFoundError during test collection via parse/__init__.py.
Moved import inside the parse method with a clear install hint.
This is the last known bare top-level optional import — sqlalchemy
(db_ingestor.py) and pdfplumber (pdf_parser.py) were fixed in prior commits.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pdfplumber (and unused PIL) were imported at module level but pdfplumber is
not installed in the [dev] extras used by CI, causing ModuleNotFoundError
during pytest collection via the parse/__init__.py import chain.
Moved import inside the method that uses it with a clear error message.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sqlalchemy was imported at module level but is not a declared dependency,
causing ModuleNotFoundError during pytest collection in CI when only [dev]
extras are installed. Moved all sqlalchemy imports inside the methods that
use them; replaced Engine type annotations with Any to avoid import-time
resolution.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix base_url from 'https://api.novita.ai/openai' to 'https://api.novita.ai/v1'
to match the OpenAI-compatible endpoint convention used by other providers
(Groq uses /openai/v1, Novita docs specify /v1)
- Rewrite test_novita_integration.py with proper pytest assertions and
pytestmark skip when NOVITA_API_KEY is unset; tests now fail on errors
instead of silently printing and returning
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove forced progress_tracker.enabled=True (was mutating global singleton)
- Wrap derive_all() fixpoint loop in try/finally so stop_tracking is always called
- Add _derived flag to cache fixpoint result; query() no longer re-runs derive_all() on every call
- Reset _derived to False in add_fact(), add_rule(), and clear()
- Warn (instead of silently drop) when add_fact() receives an unrecognised dict format
- Fix syntax error on line 9 of test file (stray dashes caused SyntaxError, broke CI)
- Add missing TestContextGraphIntegration tests: test_edge_becomes_fact and test_derive_after_load
- All 18 tests pass
Co-Authored-By: KaifAhmad1 <kaifahmad087@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix typo in ChangeCategory enum: "potenitally_breaking" → "potentially_breaking"
- Fix missing space in _classify_change description string: "New{type}" → "New {type}"
- Add null-value guard in _analyze_field_changes for unset constraint fields
- Make ChangeLogAnalyzer stateless: pass report as arg to _generate_recommendations
- Remove no-op __init__ from ChangeLogAnalyzer
- Replace non-portable emoji markers in recommendations with plain-text tags
- Extend diff_ontologies to cover individuals and axioms (not just classes/properties)
- Fix exception chaining in compare_versions: raise ... from e
- Remove silent ImportError swallow for GraphValidator (it is a first-party module)
- Add comment on deferred VersionManager import explaining circular-import reason
- Fix import-before-docstring in test_managers.py
- Add tests: version-not-found error path, individuals/axioms diff coverage,
null constraint flagged as breaking
- Fix broken Markdown link syntax in docs JSON example block
- Update docs recommendations example to match new plain-text tag format
Co-authored-by: ZohaibHassan16 <zohaib179949@gmail.com>
Co-authored-by: KaifAhmad1 <kaifahmad087@gmail.com>
- Add NovitaProvider class implementing OpenAI-compatible API
- Support for Novita AI API endpoint (https://api.novita.ai/openai)
- Configure via NOVITA_API_KEY environment variable or constructor
- Register 'novita' as built-in provider
- Update config.py to load NOVITA_API_KEY from environment
- Add test_novita_integration.py for provider testing
Default model: deepseek/deepseek-v3.2
- fix(query_engine): progress tracker leak in expand_entity_uri
stop_tracking was only called inside the `if hasattr(execute_sparql)`
block; backends without execute_sparql silently leaked a tracker entry.
Now stop_tracking(completed) is always reached on the happy path, and
stop_tracking(failed) is reached on exception.
- fix(query_engine): add skos:relatedMatch to expand_entity_uri FILTER
get_alignment_predicates() exposed relatedMatch but the SPARQL filter
did not include it, making relatedMatch alignments invisible.
- fix(query_engine): sanitize URIs in build_values_clause
URIs were interpolated raw into <{uri}> angle-bracket literals.
A URI containing > would break the VALUES clause. Now _sanitize_uri
is applied to every URI before wrapping.
- fix(engine): add skos:relatedMatch to get_alignments and list_alignments
FILTER lists now consistent with get_alignment_predicates().
- fix(engine): close SPARQL injection vector in list_alignments
Previously only " was escaped in the ontology_uri filter string.
A URI containing } would break out of the WHERE block. Now \, ", {
and } are all percent-encoded before interpolation.
- fix(engine): validate predicate is a full URI in create_alignment
Passing a CURIE like "owl:equivalentClass" silently stored a broken
triple that get_alignments() could never find. Now raises ProcessingError
with a clear message if the predicate does not start with http/https.
- fix(tests): rewrite E2E test to actually be end-to-end
test_end_to_end_cross_ontology_uri_flow was mocking expand_entity_uri
itself, so it only tested build_values_clause string formatting.
Now uses a real mock backend with execute_sparql, calls the real
expand_entity_uri, and asserts both the backend was queried and the
resulting SPARQL template contains both URIs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>