- add_decision: pass valid_from/valid_until through kwargs path so
temporal bounds are not silently dropped into metadata (Codex P1)
- add_decision: raise ValueError when Decision object and kwargs are
both provided, instead of silently ignoring the kwargs (Codex P2)
- fix guard condition to exclude decision_maker (non-None default)
to avoid false-positive ValueError on plain add_decision(obj) calls
- test_395: remove unused `import time`; strengthen as_of test with
concrete assertions on scenarios list (github-code-quality)
- test_unreleased: remove unused `import time`; drop unused `snap =`
assignment; drop unused `provider =` assignment (github-code-quality)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- test_add_decision_kwargs_form: verifies add_decision() accepts kwargs
directly (category, scenario, reasoning, outcome, confidence) without
requiring a Decision object
- test_add_decision_kwargs_and_object_both_return_id: verifies both call
forms return a non-empty string ID
- test_agent_context_inmemory_store_and_retrieve: verifies AgentContext
with VectorStore(backend="inmemory") stores memories without faiss-cpu
Closes#433
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixes#433
- ContextGraph.add_decision() now accepts keyword arguments (category,
scenario, reasoning, outcome, confidence, entities, decision_maker)
in addition to a Decision object, matching documented behaviour.
Both call forms return the decision ID string.
- Quickstart snippets in README, getting-started.md, and index.md
changed from VectorStore(backend="faiss") to VectorStore(backend="inmemory")
so they work without faiss-cpu installed.
- docs/reference/context.md methods table updated to reflect the dual
signature of add_decision().
- docs/bugs/quickstart_api_mismatch.md added to track the issue.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extends the existing ontology and triplet-store stack with first-class
SKOS support without adding any new top-level packages.
### semantica/ontology/namespace_manager.py
- `get_skos_uri(local_name)` — build full skos:core# URI from local name
- `build_concept_scheme_uri(name)` — slug a human name into a stable
ConceptScheme URI anchored at the configured base URI
### semantica/triplet_store/triplet_store.py
- `add_skos_concept(concept_uri, scheme_uri, pref_label, ...)` — asserts
ConceptScheme + Concept triples, prefLabel, altLabel, broader, narrower,
related, definition, notation via existing `add_triplets()` API
- `get_skos_concepts(scheme_uri=None)` — SPARQL SELECT via `execute_query()`,
collapses multi-valued bindings into concept dicts
### semantica/ontology/engine.py
- `list_vocabularies()` — list all skos:ConceptScheme instances
- `list_concepts(scheme_uri)` — list concepts in a scheme with alt labels
- `search_concepts(query, scheme_uri=None)` — case-insensitive substring
search over prefLabel + altLabel; sanitises user input against SPARQL injection
### tests
- `TestSKOSOntologyEngine` (14 tests) in test_ontology_comprehensive.py
- `TestSKOSTripletStore` (6 tests) in test_triplet_store.py
- All 1162 existing + new tests pass, 0 failures
### docs/reference/ontology.md
- New "SKOS Vocabulary Management" section: data-model table, import
examples (add_skos_concept + rdflib bulk), list/search API, NamespaceManager helpers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rewrote index.md to match README (tagline, badges, Problem/Solution text)
- Improved getting-started, concepts, quickstart, installation, faq, use-cases, contributing, glossary, learning-more, examples, modules, architecture, cookbook, deep-dive pages: tighter prose, fixed headings/bullets, removed inconsistencies and duplicate sections
- Removed overuse of emojis from headings in integration pages (docling, snowflake)
- Fixed change_management reference page: closed unclosed JSON code block that broke the right TOC, demoted noisy sub-headings to bold text
- CSS layout: widened content area (max-width 1440px grid, left sidebar 11rem, right TOC narrowed to 11rem for broader content), tightened TOC spacing and font size, fixed word-wrap/overflow on TOC links
- Added mkdocs_local.yml for local serving without mkdocs-jupyter plugin
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add TemporalGraphRetriever to context_retriever.py (no new file per project convention)
- Drop-in wrapper for ContextRetriever; filters related_entities/related_relationships
via reconstruct_at_time(); at_time=None is a true passthrough
- Returns new RetrievedContext objects (no in-place mutation)
- Graceful ImportError if temporal modules unavailable
- Add at_time + header_template to ContextRetriever._generate_reasoned_response()
and query_with_reasoning()
- Temporal header prepended to LLM context block only when at_time is set
- Naive datetimes normalised to UTC before formatting
- Header built with str.replace (not .format) to prevent format-string injection
- Add TemporalQueryRewriter + TemporalQueryResult to semantica/kg/
- Regex-only (default) and LLM-assisted extraction modes
- Resolves temporal phrases via TemporalNormalizer (deterministic, zero LLM)
- Word-boundary guards on intent keywords; year fallback for noun-phrase dates
- Never calls reconstruct_at_time — extraction only
- Export TemporalGraphRetriever from semantica.context
- Export TemporalQueryRewriter, TemporalQueryResult from semantica.kg
- Add 99 tests across two new test files
- tests/context/test_temporal_retriever.py (56 tests)
- tests/kg/test_temporal_query_rewriter.py (43 tests)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
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>
- Fix max_depth error message: "1 and 20" -> "1 and 100" to match actual check
- Fix Cypher query at_time param to RFC3339 UTC (append Z) for unambiguous DB comparisons
- Fix _normalize_temporal_input to raise ValueError on unparseable strings instead of returning raw input
- Fix datetime.now() -> datetime.utcnow() in recorded_at stamps and checkpoint timestamps (matches codebase convention, avoids wrong local time on Windows)
- Wrap TemporalVersionManager() construction in flush_checkpoint with clear RuntimeError
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>