Compare commits

..
Author SHA1 Message Date
Zohaib Hassnain 98900af751 Merge branch 'main' into docs-fix-model-ids 2026-09-03 22:29:39 +05:00
Zohaib Hassnain 8bceff105c docs(llms): sweep retired model as qodo found 2026-09-03 22:29:23 +05:00
Zohaib HassnainandMohd Kaif f45499b5a7 fix(deps): unblock python 3.9 core install (#1445)
Co-authored-by: Mohd Kaif <98801504+KaifAhmad1@users.noreply.github.com>
2026-09-03 22:51:43 +05:30
Zohaib Hassnain b574e2e6b4 docs: replace retired claude-sonnet-4-20250514 model id 2026-09-03 22:18:52 +05:00
Zohaib Hassnain c04adcd1a9 docs(semantic-extraction): fix summary output and model ID (#1448)
* docs(semantic-extraction): fix summary print and the model id

* chore: correct model id

* docs: make triplet valid split meaningful
2026-09-03 22:14:23 +05:00
Zohaib Hassnain a85cf913a5 docs(reasoning): clarify Datalog query result ordering (#1447)
* docs(reasoning): note DatalogReasoner.query() result is not guaranteed

* keep lists[dict] shape
2026-09-03 21:58:39 +05:00
Mohd Kaif 6ba433fea0 docs(index): rewrite landing page as a crisp developer welcome (#1446)
Replace the long feature-dump landing page with a lean "Welcome to
Semantica" page: a two-line problem/positioning statement (deterministic
semantic layer, no LLM required for graph construction, reasoning, or
provenance), five capability bullets, the multi-provider quickstart
snippet, and a 4-step onboarding path. Drops the redundant module
table, industry-use-case grid, and duplicate link lists in favor of
linking out to Core Concepts, guides, and the API reference. Keeps a
collapsed module-list accordion so the page still satisfies
docs_check.py's full-module-coverage check.
2026-09-03 22:26:38 +05:30
Zohaib Hassnain f6a0e4a32e docs(pipeline): wire configured FailureHandler into the engine (#1444) 2026-09-03 21:17:02 +05:00
Mohd Kaif 111bcf997e Revamp badges and add community links in README
Updated badge styles and added community links.
2026-09-03 21:36:23 +05:30
Zohaib Hassnain 6a07ad29be docs(modules): fix code examples to match the current API (#1443)
* docs: rewrite every code example against the actual API

* docs: address Qodo
2026-09-03 21:03:54 +05:00
Mohd Kaif 064f0eccad Merge pull request #1432 from taljeon/codex/docs-langchain-prose
docs(langchain): tighten integration prose
2026-09-03 21:03:24 +05:30
taljeon afec253451 docs(langchain): tighten integration prose 2026-09-03 21:58:36 +09:00
14 changed files with 265 additions and 182 deletions
+7 -1
View File
@@ -28,7 +28,13 @@
[![GitHub Stars](https://img.shields.io/github/stars/semantica-agi/semantica?style=flat-square&color=FFD700&logo=github&logoColor=white&label=Stars)](https://github.com/semantica-agi/semantica) [![GitHub Forks](https://img.shields.io/github/forks/semantica-agi/semantica?style=flat-square&color=6E40C9&logo=github&logoColor=white&label=Forks)](https://github.com/semantica-agi/semantica/network/members) [![Contributors](https://img.shields.io/github/contributors/semantica-agi/semantica?style=flat-square&color=2EA043&logo=github&logoColor=white)](https://github.com/semantica-agi/semantica/graphs/contributors) [![PyPI](https://img.shields.io/pypi/v/semantica.svg?style=flat-square&color=0066CC&logo=pypi&logoColor=white)](https://pypi.org/project/semantica/) [![Total Downloads](https://static.pepy.tech/badge/semantica?style=flat-square)](https://pepy.tech/project/semantica) [![Python 3.8+](https://img.shields.io/badge/python-3.8+-3776AB?style=flat-square&logo=python&logoColor=white)](https://www.python.org/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT) [![CI](https://img.shields.io/github/actions/workflow/status/semantica-agi/semantica/ci.yml?style=flat-square&label=CI)](https://github.com/semantica-agi/semantica/actions) [![Install Matrix](https://img.shields.io/github/actions/workflow/status/semantica-agi/semantica/install-matrix.yml?style=flat-square&label=pip%20install)](https://github.com/semantica-agi/semantica/actions/workflows/install-matrix.yml) [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/semantica-agi/semantica/badge?style=flat-square)](https://scorecard.dev/viewer/?uri=github.com/semantica-agi/semantica) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/semantica-agi/semantica)
[![Website](https://img.shields.io/badge/Website-getsemantica.ai-000000?style=flat-square&logo=googlechrome&logoColor=white)](https://getsemantica.ai/) [![Docs](https://img.shields.io/badge/Docs-docs.getsemantica.ai-0099FF?style=flat-square&logo=readthedocs&logoColor=white)](https://docs.getsemantica.ai/) [![Discord](https://img.shields.io/badge/Discord-Join%20Community-5865F2?style=flat-square&logo=discord&logoColor=white)](https://discord.gg/sV34vps5hH) [![Twitter/X](https://img.shields.io/badge/Follow-%40BuildSemantica-000000?style=flat-square&logo=x&logoColor=white)](https://x.com/BuildSemantica) [![YouTube](https://img.shields.io/badge/YouTube-Watch%20Demos-FF0000?style=flat-square&logo=youtube&logoColor=white)](https://www.youtube.com/watch?v=QfnNZg4-dZA) [![Changelog](https://img.shields.io/badge/Changelog-View-6E40C9?style=flat-square&logo=keepachangelog&logoColor=white)](CHANGELOG.md)
[![Website](https://img.shields.io/badge/Website-getsemantica.ai-000000?style=for-the-badge\&logo=googlechrome\&logoColor=white)](https://getsemantica.ai/)
[![Docs](https://img.shields.io/badge/Docs-docs.getsemantica.ai-0099FF?style=for-the-badge\&logo=readthedocs\&logoColor=white)](https://docs.getsemantica.ai/)
[![Community](https://img.shields.io/badge/Community-Join%20Discord-5865F2?style=for-the-badge\&logo=discord\&logoColor=white)](https://discord.gg/sV34vps5hH)
[![X](https://img.shields.io/badge/X-%40BuildSemantica-000000?style=for-the-badge\&logo=x\&logoColor=white)](https://x.com/BuildSemantica)
[![YouTube](https://img.shields.io/badge/YouTube-Watch%20Demos-FF0000?style=flat-square\&logo=youtube\&logoColor=white)](https://www.youtube.com/watch?v=QfnNZg4-dZA)
```bash
pip install semantica
+5 -5
View File
@@ -195,7 +195,7 @@ apt29_intel = context.retrieve(
```python
from semantica.llms import LiteLLM
llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
llm = LiteLLM(model="anthropic/claude-sonnet-5")
result = context.query_with_reasoning(
"What are APT29's known TTPs against healthcare infrastructure, "
@@ -281,7 +281,7 @@ context.store(
link_entities=True,
)
llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
llm = LiteLLM(model="anthropic/claude-sonnet-5")
result = context.query_with_reasoning(
"Trace the C2 infrastructure chain for APT29 operations targeting "
"ITAR-controlled contractors in 2025. Include IP ranges, ASNs, and TTPs.",
@@ -351,7 +351,7 @@ Parent: wmiprvse.exe
Sigma match: T1053.005 Scheduled Task/Job
"""
llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
llm = LiteLLM(model="anthropic/claude-sonnet-5")
triage = soc_context.query_with_reasoning(
"Triage this SIEM alert and identify the correct response runbook:\n{}".format(alert_text),
llm_provider=llm,
@@ -425,7 +425,7 @@ Patient: 68F, AF, CKD stage 3b (eGFR 32). On warfarin (INR target 2.03.0).
Presenting for elective hip replacement. Concurrent: amiodarone 200mg, atorvastatin 40mg.
"""
llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
llm = LiteLLM(model="anthropic/claude-sonnet-5")
answer = clinical_context.query_with_reasoning(
"What is the evidence-based warfarin bridging protocol for this patient "
"given CKD and amiodarone interaction risk?\n\n{}".format(patient_context),
@@ -495,7 +495,7 @@ compliance_context.store(
extract_relationships=True,
)
llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
llm = LiteLLM(model="anthropic/claude-sonnet-5")
answer = compliance_context.query_with_reasoning(
"Under Basel III CRE20, what are the RWA calculation requirements for "
"commercial real estate exposures with LTV > 80%? "
+8 -8
View File
@@ -275,20 +275,20 @@ print(data)
**LiteLLM** is a universal adapter that provides a single interface to over 100 different LLM providers, including Anthropic Claude, Azure OpenAI, AWS Bedrock, Google Vertex AI, and local Ollama instances. It acts as a translation layer, converting your unified API calls into provider-specific requests, enabling easy switching between providers without code changes.
`LiteLLM` is the Swiss Army knife. It wraps the `litellm` library, which speaks to every major provider using a unified completion API. The model string encodes both provider and model name: `"anthropic/claude-sonnet-4-20250514"`, `"azure/gpt-4o"`, `"bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0"`, `"ollama/llama3.2"`. Change the string, change the provider — no other code changes needed.
`LiteLLM` is the Swiss Army knife. It wraps the `litellm` library, which speaks to every major provider using a unified completion API. The model string encodes both provider and model name: `"anthropic/claude-sonnet-5"`, `"azure/gpt-4o"`, `"bedrock/anthropic.claude-sonnet-4-5-20250929-v1:0"`, `"ollama/llama3.2"`. Change the string, change the provider — no other code changes needed.
```python
from semantica.llms import LiteLLM
# Anthropic Claude — highest accuracy for complex reasoning
llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
llm = LiteLLM(model="anthropic/claude-sonnet-5")
# Reads ANTHROPIC_API_KEY from environment
# Azure OpenAI — compliance and data-residency requirements
llm = LiteLLM(model="azure/gpt-4o", api_key="YOUR_AZURE_KEY")
# AWS Bedrock — existing cloud agreement, no new vendor
llm = LiteLLM(model="bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0")
llm = LiteLLM(model="bedrock/anthropic.claude-sonnet-4-5-20250929-v1:0")
# Google Vertex AI
llm = LiteLLM(model="vertex_ai/gemini-1.5-pro")
@@ -306,7 +306,7 @@ The environment-variable convention for each provider: `ANTHROPIC_API_KEY`, `AZU
import os
PROVIDER_MAP = {
"prod": "anthropic/claude-sonnet-4-20250514",
"prod": "anthropic/claude-sonnet-5",
"staging": "openai/gpt-4o-mini",
"local": "ollama/llama3.2",
"azure": "azure/gpt-4o",
@@ -378,7 +378,7 @@ print("FAST: {} (conf={:.0%})".format(fast_result["response"], fast_result["con
# Tier 2: deep answer with Claude if confidence is below threshold
if fast_result["confidence"] < 0.85:
deep_llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
deep_llm = LiteLLM(model="anthropic/claude-sonnet-5")
deep_result = context.query_with_reasoning(
query, llm_provider=deep_llm, max_results=15, max_hops=3
)
@@ -574,7 +574,7 @@ print("TRIAGE: {} (conf={:.0%})".format(triage["response"], triage["confidence"]
# Tier 2: escalate to Claude for deep analysis if Tier 1 is uncertain
if triage["confidence"] < 0.88:
deep_llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
deep_llm = LiteLLM(model="anthropic/claude-sonnet-5")
deep = context.query_with_reasoning(
"Full MITRE ATT&CK analysis of this alert: identify the attack chain, "
"blast radius, affected systems, and recommended containment steps.",
@@ -630,7 +630,7 @@ for d in drugs:
# trastuzumab (conf=0.98), pertuzumab (conf=0.97), docetaxel (conf=0.96)
# Report synthesis with Claude — switch to azure/gpt-4o for HIPAA by changing one string
report_llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
report_llm = LiteLLM(model="anthropic/claude-sonnet-5")
# For HIPAA-constrained Azure deployment:
# report_llm = LiteLLM(model="azure/gpt-4o", api_key="YOUR_AZURE_KEY")
@@ -682,7 +682,7 @@ question = (
# Two-provider consensus — same query, same graph, different LLMs
gpt4o = OpenAI(model="gpt-4o", api_key="YOUR_OAI_KEY")
claude = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
claude = LiteLLM(model="anthropic/claude-sonnet-5")
answer_a = context.query_with_reasoning(question, llm_provider=gpt4o, max_results=10)
answer_b = context.query_with_reasoning(question, llm_provider=claude, max_results=10)
+4 -4
View File
@@ -197,7 +197,7 @@ reasoning_agent.load("./pipeline/enriched_intel/")
# All memories, graph nodes, and vector embeddings from both ingestion agents are now available.
# Use a high-capability model for the synthesis step
llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
llm = LiteLLM(model="anthropic/claude-sonnet-5")
synthesis = reasoning_agent.query_with_reasoning(
"Summarize the APT29 exploitation of CVE-2024-3400: affected products, "
@@ -428,7 +428,7 @@ tier1.store(
# --- Tier 2: deep investigation when Tier 1 confidence is low ---
if triage["confidence"] < 0.90:
deep_llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
deep_llm = LiteLLM(model="anthropic/claude-sonnet-5")
investigation = tier2.query_with_reasoning(
"Full MITRE ATT&CK analysis of incident {}. "
@@ -533,7 +533,7 @@ t1.start(); t2.start()
t1.join(); t2.join()
# Chief agent synthesizes across literature and experimental data
llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
llm = LiteLLM(model="anthropic/claude-sonnet-5")
synthesis = chief.query_with_reasoning(
"Identify the top two candidate compounds for KRAS G12C NSCLC that show "
@@ -576,7 +576,7 @@ credit_officer = make_desk_agent()
committee_chair = make_desk_agent()
app_id = "LOAN-2025-88421"
llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
llm = LiteLLM(model="anthropic/claude-sonnet-5")
# --- Risk Desk: PD/LGD/EL analysis ---
risk_desk.store(
+1 -1
View File
@@ -477,7 +477,7 @@ regs = [
]
# Use an LLM to extract the conceptual model from regulatory prose
llm_gen = LLMOntologyGenerator(provider="anthropic", model="claude-sonnet-4-20250514")
llm_gen = LLMOntologyGenerator(provider="anthropic", model="claude-sonnet-5")
ontology = llm_gen.generate_ontology_from_text(
"\n\n".join(r.text[:8000] for r in regs) # token-safe excerpt per document
)
+4 -2
View File
@@ -127,7 +127,7 @@ engine = ExecutionEngine(max_workers=4, retry_on_failure=True)
result = engine.execute_pipeline(pipeline)
print(f"Success: {result.success}")
print(f"Output: {result.output}") # {"node_count": 312, "edge_count": 847}
print(f"Output: {result.output}") # the final step's return value, e.g. {"node_count": ..., "edge_count": ...}
print(f"Duration: {result.metrics['execution_time']:.2f}s")
print(f"Steps completed: {result.metrics['steps_executed']}")
```
@@ -197,7 +197,9 @@ engine = ExecutionEngine(
max_workers = 4,
retry_on_failure = True,
)
# The engine uses handler.get_retry_policy(step.step_type) when a step fails
# ExecutionEngine builds its own FailureHandler; replace it with the configured one
engine.failure_handler = handler
# The engine now calls engine.failure_handler.get_retry_policy(step.step_type) on failure
```
`handler.classify_error()` distinguishes `ValidationError` (low severity, usually don't retry), `ProcessingError` (high severity), and timeout/connection errors (medium severity, always retry). You can inspect the classification:
+21 -16
View File
@@ -100,14 +100,15 @@ ner = NamedEntityRecognizer(
methods=["llm", "ml", "pattern"],
confidence_threshold=0.75,
provider="anthropic",
llm_model="claude-sonnet-4-6",
llm_model="claude-sonnet-5",
)
entities = ner.extract_entities(report)
for e in entities:
print("[{:>5.2f}] {:15s} {}".format(e.confidence, e.label, e.text))
# Expected output (abbreviated):
# Illustrative output — exact labels and scores depend on the method and model.
# Abbreviated:
# [ 0.94] THREAT_ACTOR GAMMA-7
# [ 0.91] THREAT_ACTOR DELTA-3
# [ 0.97] MALWARE HAMMERTOSS
@@ -262,16 +263,18 @@ from semantica.semantic_extract import TripletExtractor
tri = TripletExtractor(
method="llm",
provider="anthropic",
llm_model="claude-sonnet-4-6",
llm_model="claude-sonnet-5",
include_temporal=True, # attach time context to triplets when available
include_provenance=True, # embed source document reference in each triplet
validate=False, # return raw triplets; validate explicitly below
)
# Feed in the entities and relations you already extracted — the extractor
# uses them to constrain and validate what it produces
# uses them to constrain what it produces
triplets = tri.extract_triplets(report, entities, relations)
# Filter malformed triplets before serialisation
# (extract_triplets validates automatically unless validate=False, as above)
valid = tri.validate_triplets(triplets)
print("Valid: {}/{}".format(len(valid), len(triplets)))
@@ -320,7 +323,7 @@ def ingest_intel_report(
methods=[method, "pattern"],
confidence_threshold=0.70,
provider="anthropic",
llm_model="claude-sonnet-4-6",
llm_model="claude-sonnet-5",
)
entities = ner.extract_entities(text)
classified = ner.classify_entities(entities)
@@ -335,7 +338,7 @@ def ingest_intel_report(
relation_types=["deployed", "targets", "exploits", "operates_from", "provided_to"],
confidence_threshold=0.65,
provider="anthropic",
llm_model="claude-sonnet-4-6",
llm_model="claude-sonnet-5",
)
relations = rel.extract_relations(text, entities)
@@ -347,9 +350,10 @@ def ingest_intel_report(
tri = TripletExtractor(
method=method,
provider="anthropic",
llm_model="claude-sonnet-4-6",
llm_model="claude-sonnet-5",
include_temporal=True,
include_provenance=True,
validate=False, # keep raw triplets so the summary can report rejections
)
triplets = tri.extract_triplets(text, entities, relations)
valid = tri.validate_triplets(triplets)
@@ -377,6 +381,7 @@ def ingest_intel_report(
"coref_chains": len(chains),
"relations": len(relations),
"events": len(events),
"triplets_total": len(triplets),
"triplets_valid": len(valid),
"graph_nodes": graph_stats.get("graph_nodes", 0),
"graph_edges": graph_stats.get("graph_edges", 0),
@@ -402,7 +407,7 @@ for text, doc_id in reports:
summary["relations"],
summary["events"],
summary["triplets_valid"],
len(summary["rdf_turtle"]),
summary["triplets_total"],
))
```
@@ -421,7 +426,7 @@ ner = NamedEntityRecognizer(
methods=["llm", "pattern"],
confidence_threshold=0.75,
provider="anthropic",
llm_model="claude-sonnet-4-6",
llm_model="claude-sonnet-5",
)
entities = ner.extract_entities(fintel_text)
grouped = ner.classify_entities(entities)
@@ -438,14 +443,14 @@ rel = RelationExtractor(
relation_types=["operates_from", "deployed", "targets", "exploits"],
confidence_threshold=0.70,
provider="anthropic",
llm_model="claude-sonnet-4-6",
llm_model="claude-sonnet-5",
)
relations = rel.extract_relations(fintel_text, entities)
tri = TripletExtractor(
method="llm",
provider="anthropic",
llm_model="claude-sonnet-4-6",
llm_model="claude-sonnet-5",
include_temporal=True,
include_provenance=True,
)
@@ -544,14 +549,14 @@ rel = RelationExtractor(
relation_types=["treats", "causes_adverse_event", "has_efficacy", "evaluated_in"],
confidence_threshold=0.65,
provider="anthropic",
llm_model="claude-sonnet-4-6",
llm_model="claude-sonnet-5",
)
relations = rel.extract_relations(paper, entities)
tri = TripletExtractor(
method="llm",
provider="anthropic",
llm_model="claude-sonnet-4-6",
llm_model="claude-sonnet-5",
triplet_types=["treats", "has_efficacy", "causes_adverse_event"],
include_temporal=True,
include_provenance=True,
@@ -595,7 +600,7 @@ ner = NamedEntityRecognizer(
methods=["llm", "ml", "pattern"],
confidence_threshold=0.70,
provider="anthropic",
llm_model="claude-sonnet-4-6",
llm_model="claude-sonnet-5",
)
entities = ner.extract_entities(credit_memo)
grouped = ner.classify_entities(entities)
@@ -612,14 +617,14 @@ rel = RelationExtractor(
relation_types=["guaranteed_by", "secured_by", "classified_as", "exposed_to"],
confidence_threshold=0.65,
provider="anthropic",
llm_model="claude-sonnet-4-6",
llm_model="claude-sonnet-5",
)
relations = rel.extract_relations(credit_memo, entities)
tri = TripletExtractor(
method="llm",
provider="anthropic",
llm_model="claude-sonnet-4-6",
llm_model="claude-sonnet-5",
include_temporal=True,
include_provenance=True,
)
+4 -4
View File
@@ -12,13 +12,13 @@ icon: "link"
pip install "semantica[langchain]"
```
Requires `langchain-core >= 0.3`. If langchain-core is not installed, the integration still imports — every class carries the full Semantica API and degrades gracefully (`build()` returns `None`; branch on `LANGCHAIN_AVAILABLE`).
Requires `langchain-core >= 0.3`. If langchain-core is not installed, the integration still imports. Every class carries the full Semantica API and degrades gracefully (`build()` returns `None`; branch on `LANGCHAIN_AVAILABLE`).
## Components at a Glance
- **SemanticaRetriever** `BaseRetriever`: hybrid-search seeds retrieval, then graph edges are walked `hops` steps (default 2) for GraphRAG-style results.
- **SemanticaVectorStore** `VectorStore`: `add_texts` / `similarity_search` / `similarity_search_with_score` / `from_texts` over `HybridSearch`.
- **SemanticaKGTool** / **SemanticaDecisionTool** `BaseTool` subclasses: `semantica_query_graph` and `semantica_query_decisions` for LangGraph / tool-calling agents.
- **SemanticaRetriever** (`BaseRetriever`): hybrid-search seeds retrieval, then graph edges are walked `hops` steps (default 2) for GraphRAG-style results.
- **SemanticaVectorStore** (`VectorStore`): `add_texts` / `similarity_search` / `similarity_search_with_score` / `from_texts` over `HybridSearch`.
- **SemanticaKGTool** / **SemanticaDecisionTool** (`BaseTool` subclasses): `semantica_query_graph` and `semantica_query_decisions` for LangGraph / tool-calling agents.
## Component Details
+163 -122
View File
@@ -28,7 +28,9 @@ Semantica is organized into **27 modules** across six logical layers. Each modul
### Ingest
Loads data from files, web, databases, and streams into a unified `SourceDocument` format.
Loads data from files, web, databases, and streams. Each ingestor returns its own
result type (`FileIngestor``FileObject`, `WebIngestor``WebContent`, …);
document-oriented ones expose a `.text` payload and `.metadata`.
```python
from semantica.ingest import FileIngestor, WebIngestor, ParquetIngestor, XMLIngestor, DatabricksIngestor
@@ -37,7 +39,7 @@ from semantica.ingest import FileIngestor, WebIngestor, ParquetIngestor, XMLInge
ingestor = FileIngestor()
documents = ingestor.ingest_directory("data/")
# Web crawl
# Web page: returns a WebContent with .text, .title, .links, .metadata
web_ingestor = WebIngestor()
page = web_ingestor.ingest_url("https://example.com")
@@ -67,13 +69,13 @@ Extracts structured text and layout metadata from raw documents.
```python
from semantica.parse import DocumentParser, DoclingParser
# Standard parser: all common formats
# Standard parser: all common formats. parse() takes a path, returns a dict
parser = DocumentParser()
parsed = parser.parse_document("document.pdf")
parsed = parser.parse("document.pdf") # {"full_text": ..., "metadata": ..., ...}
# Advanced parser: multi-column PDFs, merged-cell tables, OCR
parser = DoclingParser(extract_tables=True, extract_images=True, output_format="markdown")
parsed = parser.parse("data/annual_report.pdf")
# Advanced parser (pip install semantica[parse-docling]): tables, OCR, layout
parser = DoclingParser(export_format="markdown", enable_ocr=True)
parsed = parser.parse("data/annual_report.pdf") # dict with full_text, tables, pages
```
**Available parsers:** `DocumentParser`, `DoclingParser`, `CodeParser`, `CSVParser`, `DocxParser`, `EmailParser`, `ExcelParser`, `HTMLParser`, `ImageParser`, `JSONParser`, `MCPParser`, `MediaParser`, `PDFParser`, `PPTXParser`, `StructuredDataParser`, `WebParser`, `XMLParser`
@@ -85,11 +87,12 @@ Chunks text for embedding and RAG pipelines with awareness of semantic boundarie
```python
from semantica.split import TextSplitter
splitter = TextSplitter(method="semantic_transformer")
chunks = splitter.split(text, chunk_size=1000, chunk_overlap=200)
# chunk_size / chunk_overlap are constructor arguments
splitter = TextSplitter(method="semantic_transformer", chunk_size=1000, chunk_overlap=200)
chunks = splitter.split(text)
```
**Chunking strategies:** `recursive`, `semantic_transformer`, `entity_aware`, `relation_aware`, `sliding_window`, `structural`
**Chunking methods:** `recursive`, `token`, `sentence`, `paragraph`, `semantic_transformer`, `entity_aware`, `relation_aware`, `graph_based`, `ontology_aware`, `hierarchical`, `community_detection`, `centrality_based`, `llm`
### Normalize
@@ -115,17 +118,18 @@ Named entity recognition, relation extraction, and triplet generation.
```python
from semantica.semantic_extract import NERExtractor, RelationExtractor, TripletExtractor
ner = NERExtractor(method="llm", llm_provider=llm)
entities = ner.extract("Apple Inc. was founded by Steve Jobs.")
# LLM method: provider + llm_model select the backend; the API key comes from the env
ner = NERExtractor(method="llm", provider="groq", llm_model="llama-3.3-70b-versatile")
entities = ner.extract("Apple Inc. was founded by Steve Jobs.") # list[Entity]
rel = RelationExtractor(method="llm", llm_provider=llm)
relationships = rel.extract(text, entities=entities)
rel = RelationExtractor(method="llm", provider="groq", llm_model="llama-3.3-70b-versatile")
relationships = rel.extract(text, entities=entities) # list[Relation]
trip = TripletExtractor(method="llm", llm_provider=llm)
triplets = trip.extract(text)
trip = TripletExtractor(method="pattern")
triplets = trip.extract(text) # list[Triplet]
```
**Extraction methods:** `"pattern"` (no API key), `"ml"` (local model), `"llm"` (any of the 8 supported providers)
**Extraction methods:** `"pattern"` (no API key), `"ml"` (local spaCy model), `"llm"` (any of the 9 supported providers)
**Additional extractors:** `CoreferenceResolver`, `EventDetector`, `SemanticAnalyzer`, `SemanticNetworkExtractor`
@@ -137,17 +141,17 @@ Graph construction, graph algorithms, temporal model, and distance intelligence.
from semantica.kg import GraphBuilder, GraphAnalyzer, TemporalGraphQuery, SimilarityCalculator
from datetime import datetime
# Build
# Build: build() takes a {"entities": ..., "relationships": ...} dict
builder = GraphBuilder(merge_entities=True)
kg = builder.build(entities=entities, relationships=relationships)
kg = builder.build({"entities": entities, "relationships": relationships})
# Temporal graphs (v0.4.0)
query_engine = TemporalGraphQuery(enable_temporal_reasoning=True)
snapshot = query_engine.query_at_time(kg, query="", at_time=datetime(2021, 6, 15))
# Semantic similarity (v0.5.0)
calc = SimilarityCalculator()
scores = calc.calculate_similarity(entity_a, entity_b)
# Semantic similarity (v0.5.0): operates on embedding vectors
calc = SimilarityCalculator(method="cosine")
score = calc.cosine_similarity(vec_a, vec_b)
```
**Graph algorithms available:** centrality calculation, community detection, connectivity analysis, entity resolution, link prediction, path finding, similarity calculation
@@ -175,19 +179,23 @@ Derives new facts from existing knowledge using multiple inference strategies.
```python
from semantica.reasoning import Reasoner, DatalogReasoner
# Rule-based reasoning
# Forward chaining: facts and rules as predicate(args) / IF-THEN strings
engine = Reasoner()
engine.apply_transitivity("located_in")
engine.apply_symmetry("knows")
result = engine.infer()
engine.add_fact("Manager(Alice)")
engine.add_rule("IF Manager(?x) THEN HasAuthority(?x)")
results = engine.forward_chain() # list[InferenceResult] with .conclusion, .rule_used
# Datalog: recursive Horn clause rules (v0.4.0)
datalog = DatalogEngine()
datalog = DatalogReasoner()
datalog.add_fact("parent(tom, bob)")
datalog.add_fact("parent(bob, ann)")
datalog.add_rule("ancestor(X, Y) :- parent(X, Y).")
datalog.add_rule("ancestor(X, Z) :- parent(X, Y), ancestor(Y, Z).")
results = datalog.query("ancestor(alice, ?)")
datalog.derive_all()
results = datalog.query("ancestor(tom, ?Z)") # [{"Z": "bob"}, {"Z": "ann"}], order not guaranteed
```
**Engines:** forward chaining, Rete network, deductive, abductive, SPARQL, Datalog: all produce explainable inference paths
**Engines:** `Reasoner` (forward/backward chaining), `ReteEngine`, `SPARQLReasoner`, `DatalogReasoner`, `TemporalReasoningEngine`, `GraphReasoner` (LLM)
## Storage
@@ -199,9 +207,9 @@ Generates and manages vector embeddings for semantic similarity.
```python
from semantica.embeddings import EmbeddingGenerator
generator = EmbeddingGenerator(model="sentence-transformers")
embeddings = generator.generate(["text1", "text2"])
similarity = generator.similarity(embeddings[0], embeddings[1])
generator = EmbeddingGenerator()
embeddings = generator.generate_embeddings(["text1", "text2"]) # np.ndarray
similarity = generator.compare_embeddings(embeddings[0], embeddings[1])
```
**Supported models:** Sentence-Transformers, FastEmbed, OpenAI, BGE
@@ -215,12 +223,18 @@ Multi-backend vector database with hybrid search support.
```python
from semantica.vector_store import VectorStore
store = VectorStore(backend="faiss", dimension=768)
store.add_vectors(embeddings, ids)
results = store.search(query_vector, top_k=10)
store = VectorStore(backend="faiss", dimension=768)
# Raw vectors
ids = store.store_vectors(embeddings) # returns generated ids
hits = store.search_vectors(query_vector, k=10)
# Or store text and let the store embed it
store.add_documents(["Apple was founded in 1976.", "Google was founded in 1998."])
results = store.search("tech company founding dates", limit=10)
```
**Backends:** FAISS, Pinecone, Weaviate, Qdrant, Milvus, PgVector, in-memory
**Backends:** FAISS, Pinecone, Weaviate, Qdrant, Milvus, PgVector, SQLite, in-memory
**Search modes:** semantic top-k, hybrid (vector + keyword), metadata-filtered
@@ -232,8 +246,8 @@ Connects to graph databases for persistent, query-able storage.
from semantica.graph_store import GraphStore
store = GraphStore(backend="neo4j")
store.add_nodes(entities)
store.add_edges(relationships)
store.add_nodes([{"id": "acme", "type": "Organization", "properties": {"name": "Acme"}}])
store.add_edges([{"source": "alice", "target": "acme", "type": "works_for"}])
results = store.query("MATCH (n)-[r]->(m) RETURN n, r, m")
```
@@ -246,9 +260,9 @@ RDF triple-based storage with SPARQL query support.
```python
from semantica.triplet_store import TripletStore
store = TripletStore(backend="blazegraph")
store.add_triplets(subject, predicate, obj)
results = store.sparql("SELECT ?s ?p ?o WHERE { ?s ?p ?o }")
store = TripletStore(backend="oxigraph")
store.add_triplets(triplets) # list of Triplet objects (or add_triplet for one)
results = store.execute_query("SELECT ?s ?p ?o WHERE { ?s ?p ?o }")
```
**Backends:** Oxigraph (embedded), Blazegraph, Apache Jena, RDF4J
@@ -261,15 +275,18 @@ results = store.sparql("SELECT ?s ?p ?o WHERE { ?s ?p ?o }")
Detects, scores, and merges duplicate entities across sources.
```python
from semantica.deduplication import EntityResolver
from semantica.deduplication import DuplicateDetector, EntityMerger
resolver = EntityResolver()
merged = resolver.resolve(entities, strategy="semantic_v2")
detector = DuplicateDetector(similarity_threshold=0.85)
candidates = detector.detect_duplicates(entities)
merger = EntityMerger()
operations = merger.merge_duplicates(entities, strategy="keep_most_complete")
```
**v2 strategies** (`blocking_v2`, `hybrid_v2`, `semantic_v2`) are up to 7x faster than v1.
**v2 candidate-generation modes** (`blocking_v2`, `hybrid_v2`, `semantic_v2`) are up to 7x faster than v1.
**Components:** `EntityResolver`, `DuplicateDetector`, `EntityMerger`, `SimilarityCalculator`, `ClusterBuilder`
**Components:** `DuplicateDetector`, `EntityMerger`, `ClusterBuilder`, `MergeStrategyManager`
**`DuplicateDetector` options:** `max_results`, `top_k_per_entity`, `min_similarity`, `sort_by`
@@ -278,14 +295,13 @@ merged = resolver.resolve(entities, strategy="semantic_v2")
Detects and resolves fact conflicts across overlapping knowledge sources.
```python
from semantica.conflicts import ConflictDetector
from semantica.conflicts import ConflictDetector, ConflictResolver
detector = ConflictDetector()
conflicts = detector.detect_conflicts(kg)
resolved = detector.resolve(conflicts, strategy="most_recent")
conflicts = ConflictDetector().detect_conflicts(entities) # list of entity dicts
resolved = ConflictResolver().resolve_conflicts(conflicts, strategy="most_recent")
```
**Detection types:** value conflicts, type conflicts, temporal conflicts, logical conflicts
**Detection types:** value conflicts, type conflicts, relationship conflicts, temporal conflicts, logical conflicts
**Resolution strategies:** prefer most recent, prefer most reliable source, majority vote, flag for manual review
@@ -298,6 +314,7 @@ Agent context graphs, decision tracking, causal chains, and precedent search.
```python
from semantica.context import AgentContext, ContextGraph
from semantica.vector_store import VectorStore
context = AgentContext(
vector_store=VectorStore(backend="faiss", dimension=768),
@@ -328,7 +345,7 @@ W3C PROV-O compliant lineage tracking across all modules.
from semantica.provenance import ProvenanceManager
manager = ProvenanceManager()
manager.track_entity("entity_1", "document.pdf", "person")
manager.track_entity("entity_1", source="document.pdf", metadata={"type": "person"})
lineage = manager.get_lineage("entity_1")
```
@@ -364,8 +381,8 @@ RDFExporter().export(graph, file_path="graph.ttl", format="turtle")
# Analytics
ParquetExporter().export(graph, file_path="output/graph.parquet")
# ArangoDB
aql = ArangoAQLExporter().export(graph)
# ArangoDB: writes AQL INSERT statements to the given path
ArangoAQLExporter().export(graph, file_path="graph.aql")
```
**Export formats:** RDF (Turtle, JSON-LD, N-Triples, XML), Parquet, ArangoDB AQL, CSV, OWL, Arrow, LPG, YAML, distance matrices
@@ -390,16 +407,24 @@ viz.visualize_network(graph, output="html", file_path="graph.html")
Pipeline DSL with parallel workers, retry policies, and failure handling.
```python
from semantica.pipeline import Pipeline
from semantica.pipeline import PipelineBuilder, ExecutionEngine
from semantica.ingest import FileIngestor
from semantica.semantic_extract import NERExtractor
pipeline = Pipeline()
pipeline.add_step("ingest", FileIngestor())
pipeline.add_step("extract", NERExtractor())
pipeline.add_step("build", GraphBuilder())
result = pipeline.run("data/")
builder = PipelineBuilder()
# Each step type dispatches to a handler you register (or supply explicitly)
builder.register_step_handler("ingest", lambda data, **c: FileIngestor().ingest(c["source"]))
builder.register_step_handler("extract", lambda docs, **c: NERExtractor(method="pattern").extract(docs[0].text))
builder.add_step("ingest", step_type="ingest", source="data/")
builder.add_step("extract", step_type="extract")
pipeline = builder.connect_steps("ingest", "extract").build(name="docs_to_entities")
result = ExecutionEngine().execute_pipeline(pipeline)
```
**Components:** `Pipeline`, `PipelineBuilder`, `ExecutionEngine`, `FailureHandler`, `PipelineValidator`, `ParallelismManager`, `ResourceScheduler`
**Components:** `PipelineBuilder`, `Pipeline`, `ExecutionEngine`, `FailureHandler`, `PipelineValidator`, `ParallelismManager`, `ResourceScheduler`
### Explorer
@@ -428,7 +453,7 @@ llm = OpenAI(model="gpt-4o", api_key=os.getenv("OPENAI_API_KEY"))
llm = LiteLLM(model="anthropic/claude-opus-4-7", api_key=os.getenv("ANTHROPIC_API_KEY"))
```
**Supported providers:** OpenAI, Anthropic, Google Gemini, Groq, Ollama, DeepSeek, Novita AI, LiteLLM (20+ models via one interface)
**Supported providers:** OpenAI, Anthropic, Google Gemini, Groq, Ollama, DeepSeek, Novita AI, HuggingFace, plus LiteLLM (100+ models via one interface)
### MCP Server
@@ -445,44 +470,43 @@ python -m semantica.mcp_server
Bootstrap knowledge graphs from verified structured sources: fixed-point reference data, controlled vocabularies, and domain anchors.
```python
from semantica.seed import SeedManager
from semantica.seed import SeedDataManager
seed = SeedManager()
seed.populate(kg, dataset="companies", count=100)
seed = SeedDataManager()
# Load domain seeds from file or built-in datasets
seed.load_from_file("seed_data/industries.json")
seed.inject(kg) # merges seed nodes without duplicating existing entities
# Load trusted reference data from CSV / JSON / a database / an API
seed_data = seed.load_from_csv("seed_data/industries.csv", entity_type="Industry")
# Merge seed data with extraction output (seed values win on conflict by default)
combined = seed.integrate_with_extracted(
{"entities": seed_data, "relationships": []},
{"entities": extracted_entities, "relationships": extracted_relationships},
merge_strategy="seed_first",
)
```
**Use cases:** anchoring extraction with known entities, pre-populating ontology classes, deterministic test graph generation.
### Evals
Evaluation framework for measuring KG quality, extraction accuracy, and pipeline performance.
Scores decision-intelligence outputs (decision records, audit trails, reasoning
text) with a registry of deterministic and model-backed evaluators plus a small
run harness.
```python
from semantica.evals import KGEvaluator, ExtractionEvaluator, PipelineEvaluator, RegressionTracker
from semantica.evals import evaluate, list_evaluators
# KG quality
report = KGEvaluator().evaluate(kg, ontology=ontology)
print(f"Completeness: {report.completeness:.2%} Consistency: {report.consistency:.2%}")
list_evaluators()
# ['decision_scores', 'exact_match', 'keyword_check', 'length_range',
# 'levenshtein', 'llm_as_judge', 'numeric_range', 'regex_match', 'rouge',
# 'temporal_range']
# Extraction accuracy
report = ExtractionEvaluator().evaluate_ner(predictions=extracted, gold_standard=annotated)
print(f"Precision: {report.precision:.3f} Recall: {report.recall:.3f} F1: {report.f1:.3f}")
# Pipeline throughput and latency
metrics = PipelineEvaluator().benchmark(pipeline, data="data/", bench_runs=5)
print(f"Throughput: {metrics.docs_per_second:.1f} docs/sec")
# Regression tracking across runs
tracker = RegressionTracker(db_path="eval_history.db")
run_id = tracker.record_run(pipeline_version="v1.2.0", metrics=metrics)
diff = tracker.compare(run_id, baseline_run_id="run_abc123")
cases = [("apple", "aple"), ("night", "nacht")]
summary = evaluate(cases, evaluators=["levenshtein"])
print(summary.total, summary.passed, summary.pass_rate)
```
**Components:** `KGEvaluator`, `ExtractionEvaluator`, `PipelineEvaluator`, `RegressionTracker`
**Public API:** `evaluate(cases, evaluators, config=None)`, `list_evaluators()`, `get_evaluator(name)`, and the `EvalMetric` / `CaseResult` / `EvalSummary` result types. See the [Evals reference](/reference/evals).
### Core
@@ -491,20 +515,20 @@ Base classes, shared data models, and the plugin registry used across all module
```python
from semantica.core import Semantica, PluginRegistry, ConfigManager
# Top-level orchestrator
sem = Semantica(config_path="config.yaml")
# ConfigManager loads a Config; Config.get() does dotted lookups
config = ConfigManager().load_from_file("config.yaml")
batch = config.get("processing.batch_size", default=32)
# Top-level orchestrator: pass the Config object (or a dict), not a path
sem = Semantica(config=config)
sem.initialize()
# Plugin registry: register custom components
# Plugin registry: register custom components under a name
registry = PluginRegistry()
registry.register("my_ingestor", MyCustomIngestor)
# Config management
config = ConfigManager(config_path="config.yaml")
batch = config.get("processing.batch_size", default=32)
registry.register_plugin("my_ingestor", MyCustomIngestor, version="1.0.0")
```
**Components:** `Semantica`, `PluginRegistry`, `ConfigManager`, `LifecycleManager`, `HealthMonitor`, `Config`
**Components:** `Semantica`, `PluginRegistry`, `ConfigManager`, `Config`, `LifecycleManager`, `HealthStatus`, `MethodRegistry`
### Utils
@@ -532,11 +556,13 @@ from semantica.semantic_extract import NERExtractor, RelationExtractor
from semantica.kg import GraphBuilder
sources = FileIngestor().ingest("data/")
parsed = DocumentParser().parse(sources[0])
entities = NERExtractor(method="llm", llm_provider=llm).extract(parsed)
relationships = RelationExtractor(method="llm", llm_provider=llm).extract(parsed, entities=entities)
text = DocumentParser().parse(sources[0].path)["full_text"]
ner = NERExtractor(method="llm", provider="groq", llm_model="llama-3.3-70b-versatile")
rel = RelationExtractor(method="llm", provider="groq", llm_model="llama-3.3-70b-versatile")
entities = ner.extract(text)
relationships = rel.extract(text, entities=entities)
graph = GraphBuilder(merge_entities=True).build(
entities=entities, relationships=relationships
{"entities": entities, "relationships": relationships}
)
```
@@ -555,16 +581,20 @@ from semantica.vector_store import VectorStore
context = AgentContext(
vector_store=VectorStore(backend="faiss", dimension=768),
knowledge_graph=ContextGraph(advanced_analytics=True),
graph_expansion=True,
)
context.load_graph("company_kg.json")
result = context.query(
# store() extracts entities and populates the graph + vector index
context.store([{"content": "Steve Wozniak co-founded Apple with Steve Jobs."}])
# retrieve() blends vector similarity with multi-hop graph traversal
results = context.retrieve(
"What companies did Apple alumni found?",
mode="graphrag",
reasoning=True,
use_graph=True,
expand_graph=True,
)
for claim in result.claims:
print(f"{claim.text} → {claim.source_node}")
for r in results:
print(f"[{r['score']:.3f}] {r['content']} (source: {r['source']})")
```
**Best for:** question-answering systems, RAG with source attribution, research assistants
@@ -606,18 +636,22 @@ precedents = context.find_precedents("model selection", limit=5)
```python
from semantica.ingest import FileIngestor
from semantica.parse import DocumentParser
from semantica.semantic_extract import NERExtractor
from semantica.kg import GraphBuilder
from semantica.provenance import ProvenanceManager
from semantica.export import RDFExporter
sources = FileIngestor().ingest("records/")
entities = NERExtractor(method="llm", llm_provider=llm).extract(sources)
graph = GraphBuilder(merge_entities=True).build(entities=entities, relationships=[])
prov = ProvenanceManager()
lineage = prov.get_entity_lineage("entity_id")
ner = NERExtractor(method="llm", provider="groq", llm_model="llama-3.3-70b-versatile")
entities = ner.extract(DocumentParser().parse(sources[0].path)["full_text"])
graph = GraphBuilder(merge_entities=True).build({"entities": entities, "relationships": []})
RDFExporter(include_provenance=True).export(graph, file_path="audit.ttl", format="turtle")
prov = ProvenanceManager()
prov.track_entity("entity_id", source="records/filing.pdf", metadata={"extractor": "llm"})
lineage = prov.get_lineage("entity_id")
RDFExporter().export(graph, file_path="audit.ttl", format="turtle")
```
**Best for:** HIPAA, SOX, GDPR, FDA 21 CFR Part 11 deployments
@@ -632,18 +666,25 @@ RDFExporter(include_provenance=True).export(graph, file_path="audit.ttl", format
from semantica.ingest import WebIngestor
from semantica.normalize import TextNormalizer
from semantica.semantic_extract import NERExtractor, RelationExtractor
from semantica.graph_store import Neo4jStore
from semantica.graph_store import GraphStore
from semantica.kg import GraphBuilder
pages = WebIngestor(max_depth=2).ingest("https://example.com")
ingestor = WebIngestor()
normalizer = TextNormalizer()
store = Neo4jStore(uri="bolt://localhost:7687", user="neo4j", password="password")
ner = NERExtractor(method="pattern")
rel = RelationExtractor(method="pattern")
for page in pages:
# The generic GraphStore wrapper exposes the add_nodes/add_edges interface
# GraphBuilder persists through; a raw Neo4jStore does not
store = GraphStore(backend="neo4j", uri="bolt://localhost:7687", user="neo4j", password="password")
builder = GraphBuilder(merge_entities=True, graph_store=store)
for url in ["https://example.com/a", "https://example.com/b"]:
page = ingestor.ingest_url(url) # WebContent, has .text
text = normalizer.normalize_text(page.text)
entities = NERExtractor().extract(text)
relationships = RelationExtractor().extract(text, entities=entities)
store.add_nodes(entities)
store.add_edges(relationships)
entities = ner.extract(text)
relationships = rel.extract(text, entities=entities)
builder.build({"entities": entities, "relationships": relationships})
```
**Best for:** competitive intelligence, news monitoring, research aggregation
@@ -692,8 +733,8 @@ versioner.create_snapshot(kg, "2024-Q1", author="user@example.com", description=
| [vector_store](/reference/vector_store) | Vector database | `VectorStore` |
| [graph_store](/reference/graph_store) | Graph database | `GraphStore` |
| [triplet_store](/reference/triplet_store) | RDF triple store | `TripletStore` |
| [deduplication](/reference/deduplication) | Entity resolution | `EntityResolver`, `DuplicateDetector`, `ClusterBuilder`, `MergeStrategyManager` |
| [conflicts](/reference/conflicts) | Conflict resolution | `ConflictDetector` |
| [deduplication](/reference/deduplication) | Entity resolution | `DuplicateDetector`, `EntityMerger`, `ClusterBuilder`, `MergeStrategyManager` |
| [conflicts](/reference/conflicts) | Conflict resolution | `ConflictDetector`, `ConflictResolver`, `SourceTracker` |
| [context](/reference/context) | Agent context & decisions | `AgentContext`, `ContextGraph` |
| [provenance](/reference/provenance) | W3C PROV-O lineage | `ProvenanceManager` |
| [change_management](/reference/change_management) | Version control | `TemporalVersionManager` |
@@ -703,8 +744,8 @@ versioner.create_snapshot(kg, "2024-Q1", author="user@example.com", description=
| [explorer](/reference/explorer) | Knowledge Explorer UI | `semantica-explorer --graph <file>` |
| [llms](/reference/llms) | LLM providers | `Groq`, `OpenAI`, `create_provider` |
| [mcp_server](/reference/mcp_server) | MCP stdio server | `python -m semantica.mcp_server` |
| [seed](/reference/seed) | KG bootstrapping from structured sources | `SeedManager` |
| [evals](/reference/evals) | Quality evaluation | `KGEvaluator`, `ExtractionEvaluator`, `PipelineEvaluator`, `RegressionTracker` |
| [seed](/reference/seed) | KG bootstrapping from structured sources | `SeedDataManager` |
| [evals](/reference/evals) | Decision-intelligence evaluation | `evaluate`, `list_evaluators`, `EvalSummary` |
| [core](/reference/core) | Base classes & registry | `Semantica`, `ConfigManager`, `PluginRegistry`, `LifecycleManager` |
| [utils](/reference/utils) | Shared utilities | `helpers`, `validators` |
+7 -7
View File
@@ -129,7 +129,7 @@ from semantica.llms import Groq, OpenAI, LiteLLM, HuggingFaceLLM
from semantica.llms import LiteLLM
llm = LiteLLM(
model="anthropic/claude-sonnet-4-20250514",
model="anthropic/claude-sonnet-5",
api_key=os.getenv("ANTHROPIC_API_KEY"),
temperature=0.0,
)
@@ -198,7 +198,7 @@ llm = Groq(api_key=os.getenv("GROQ_API_KEY"), model="llama-3.1-8b-instant")
# Method 3: Multiple providers via LiteLLM
providers = {
"fast": LiteLLM(model="groq/llama-3.1-8b-instant", api_key=os.getenv("GROQ_API_KEY")),
"smart": LiteLLM(model="anthropic/claude-sonnet-4-20250514", api_key=os.getenv("ANTHROPIC_API_KEY"))
"smart": LiteLLM(model="anthropic/claude-sonnet-5", api_key=os.getenv("ANTHROPIC_API_KEY"))
}
```
@@ -252,7 +252,7 @@ from semantica.llms import LiteLLM
# pip install "semantica[llm-litellm]"
# Anthropic Claude
llm = LiteLLM(model="anthropic/claude-opus-4-5", api_key=os.getenv("ANTHROPIC_API_KEY"))
llm = LiteLLM(model="anthropic/claude-opus-4-7", api_key=os.getenv("ANTHROPIC_API_KEY"))
# Google Gemini
llm = LiteLLM(model="gemini/gemini-1.5-pro", api_key=os.getenv("GOOGLE_API_KEY"))
@@ -267,7 +267,7 @@ llm = LiteLLM(model="deepseek/deepseek-chat", api_key=os.getenv("DEEP
llm = LiteLLM(model="azure/gpt-4o", api_key=os.getenv("AZURE_API_KEY"))
# AWS Bedrock
llm = LiteLLM(model="bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0")
llm = LiteLLM(model="bedrock/anthropic.claude-sonnet-4-5-20250929-v1:0")
# Novita AI
llm = LiteLLM(model="novita/deepseek/deepseek-v3.2", api_key=os.getenv("NOVITA_API_KEY"))
@@ -297,12 +297,12 @@ from semantica.llms import LiteLLM
# Pattern: LiteLLM(model="<provider>/<model-name>")
providers = {
"Anthropic": LiteLLM(model="anthropic/claude-opus-4-5", api_key=os.getenv("ANTHROPIC_API_KEY")),
"Anthropic": LiteLLM(model="anthropic/claude-opus-4-7", api_key=os.getenv("ANTHROPIC_API_KEY")),
"Gemini": LiteLLM(model="gemini/gemini-1.5-pro", api_key=os.getenv("GOOGLE_API_KEY")),
"Ollama": LiteLLM(model="ollama/llama3.2:3b", api_base="http://localhost:11434"),
"DeepSeek": LiteLLM(model="deepseek/deepseek-chat", api_key=os.getenv("DEEPSEEK_API_KEY")),
"Azure": LiteLLM(model="azure/gpt-4o", api_key=os.getenv("AZURE_API_KEY")),
"Bedrock": LiteLLM(model="bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0"),
"Bedrock": LiteLLM(model="bedrock/anthropic.claude-sonnet-4-5-20250929-v1:0"),
"Cohere": LiteLLM(model="cohere/command-r-plus", api_key=os.getenv("COHERE_API_KEY")),
"Novita AI": LiteLLM(model="novita/deepseek/deepseek-v3.2", api_key=os.getenv("NOVITA_API_KEY")),
}
@@ -416,7 +416,7 @@ for text in texts:
| :---------- | :--------------------------- | :----------- |
| **Entity Extraction** | `Groq("llama-3.3-70b-versatile")` | Fast, good accuracy for structured tasks |
| **Relation Extraction** | `OpenAI("gpt-4o")` | Best at complex relationship reasoning |
| **Complex Analysis** | `LiteLLM("anthropic/claude-sonnet-4-20250514")` | Highest reasoning capability |
| **Complex Analysis** | `LiteLLM("anthropic/claude-sonnet-5")` | Highest reasoning capability |
| **High Volume/Cost** | `LiteLLM("deepseek/deepseek-chat")` | Lowest cost per token |
### Error Handling
+1 -1
View File
@@ -323,7 +323,7 @@ all_facts = datalog.derive_all()
# Query with variable pattern: variables start with uppercase or ?
results = datalog.query("ancestor(alice, ?Z)")
# → [{"Z": "bob"}, {"Z": "charlie"}, {"Z": "dave"}]
# → a list of binding dicts: [{"Z": "bob"}, {"Z": "charlie"}, {"Z": "dave"}] (order not guaranteed)
# Clear and start over
datalog.clear()
+36 -7
View File
@@ -47,7 +47,11 @@ dependencies = [
"numpy>=2.0.2",
"pandas>=1.3.0",
"scipy>=1.13.1",
"scikit-learn>=1.7.2",
# scikit-learn dropped Python 3.9 support at 1.7.0 (requires_python >=3.10),
# so an unqualified >=1.7.2 floor is unsatisfiable on 3.9. Cap 3.9 to the
# last 3.9-compatible release line; 3.10+ is left unconstrained.
"scikit-learn>=1.6.1,<1.7.0; python_version < '3.10'",
"scikit-learn>=1.7.2; python_version >= '3.10'",
"umap-learn>=0.5.12",
# thinc (spacy's core dep) dropped Python 3.9 wheels at 8.3.10, and later
# spacy patch releases (3.8.8+) require thinc>=8.3.9-only-on-3.10+ ranges,
@@ -66,24 +70,49 @@ dependencies = [
"seaborn>=0.13.2",
"plotly>=6.8.0",
"ipywidgets>=8.0.0",
"requests>=2.34.2",
# requests dropped Python 3.9 support at 2.33.0 (requires_python >=3.10),
# so an unqualified >=2.34.2 floor is unsatisfiable on 3.9. Cap 3.9 to the
# last 3.9-compatible release; 3.10+ is left unconstrained.
"requests>=2.32.5,<2.33.0; python_version < '3.10'",
"requests>=2.34.2; python_version >= '3.10'",
"GitPython>=3.1.58",
"chardet>=7.4.3",
# chardet dropped Python 3.9 support at 6.0.0 (requires_python >=3.10), so
# an unqualified >=7.4.3 floor is unsatisfiable on 3.9. Cap 3.9 to the last
# 3.9-compatible release; 3.10+ is left unconstrained.
"chardet>=5.2.0,<6.0.0; python_version < '3.10'",
"chardet>=7.4.3; python_version >= '3.10'",
"protobuf>=5.29.1,<8.0",
"grpcio>=1.81.1",
# grpcio dropped Python 3.9 support at 1.81.0 (requires_python >=3.10), so
# an unqualified >=1.81.1 floor is unsatisfiable on 3.9. Cap 3.9 to the last
# 3.9-compatible release; 3.10+ is left unconstrained.
"grpcio>=1.80.0,<1.81.0; python_version < '3.10'",
"grpcio>=1.81.1; python_version >= '3.10'",
"beautifulsoup4>=4.15.0",
"lxml>=6.1.1",
"python-docx>=1.2.0",
"openpyxl>=3.1.5",
"pillow>=12.2.0",
# pillow dropped Python 3.9 support at 12.0.0 (requires_python >=3.10), so
# an unqualified >=12.2.0 floor is unsatisfiable on 3.9. Cap 3.9 to the last
# 3.9-compatible release; 3.10+ is left unconstrained.
"pillow>=11.3.0,<12.0.0; python_version < '3.10'",
"pillow>=12.2.0; python_version >= '3.10'",
"librosa>=0.9.0",
"opencv-python>=4.13.0.92",
"faiss-cpu>=1.7.0",
"fastembed>=0.2.0",
"onnxruntime>=1.20.1",
# onnxruntime stopped shipping cp39 wheels at 1.20.0 (its PyPI metadata
# still claims requires_python >=3.9, but no matching wheel exists), so an
# unqualified >=1.20.1 floor is unsatisfiable on 3.9. Cap 3.9 to the last
# release with a cp39 wheel; 3.10+ is left unconstrained.
"onnxruntime>=1.19.2,<1.20.0; python_version < '3.10'",
"onnxruntime>=1.20.1; python_version >= '3.10'",
"tokenizers>=0.15.0",
"pydantic>=2.13.4",
"click>=8.4.2",
# click dropped Python 3.9 support at 8.2.0 (requires_python >=3.10), so an
# unqualified >=8.4.2 floor is unsatisfiable on 3.9. Cap 3.9 to the last
# 3.9-compatible release; 3.10+ is left unconstrained.
"click>=8.1.8,<8.2.0; python_version < '3.10'",
"click>=8.4.2; python_version >= '3.10'",
"rich>=12.5.0",
"tqdm>=4.68.3",
"pyyaml>=6.0",
+1 -1
View File
@@ -35,7 +35,7 @@ Example Usage:
>>> llm = LiteLLM(model="openai/gpt-4o", api_key="your-key")
>>> response = llm.generate("Hello, world!")
>>> # Or use other providers via LiteLLM
>>> llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
>>> llm = LiteLLM(model="anthropic/claude-sonnet-5")
>>> response = llm.generate("Hello, world!")
>>>
>>> # Anthropic provider
+3 -3
View File
@@ -31,7 +31,7 @@ class LiteLLM:
Provides unified interface to 100+ LLM providers through LiteLLM library.
Supports providers like OpenAI, Anthropic, Groq, Azure, Bedrock, Vertex AI, etc.
Model format: "provider/model-name" (e.g., "openai/gpt-4o", "anthropic/claude-sonnet-4-20250514", "groq/llama-3.1-8b-instant")
Model format: "provider/model-name" (e.g., "openai/gpt-4o", "anthropic/claude-sonnet-5", "groq/llama-3.1-8b-instant")
Example:
>>> from semantica.llms import LiteLLM
@@ -39,7 +39,7 @@ class LiteLLM:
>>> response = llm.generate("What is AI?")
>>>
>>> # Use with different providers
>>> llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
>>> llm = LiteLLM(model="anthropic/claude-sonnet-5")
>>> response = llm.generate("Hello!")
"""
@@ -54,7 +54,7 @@ class LiteLLM:
Args:
model: Model identifier in format "provider/model-name"
Examples: "openai/gpt-4o", "anthropic/claude-sonnet-4-20250514",
Examples: "openai/gpt-4o", "anthropic/claude-sonnet-5",
"groq/llama-3.1-8b-instant", "azure/gpt-4", etc.
api_key: API key (optional, can use environment variables)
**kwargs: Additional LiteLLM options (temperature, max_tokens, etc.)