Metadata-Version: 2.4
Name: aiecs-kg
Version: 0.9.0a1
Summary: Enterprise knowledge graph (L2) — optional PyPI package split from AIECS
Author-email: AIECS Team <iretbl@gmail.com>
License: Apache-2.0
Project-URL: Homepage, https://github.com/Howmany-Zeta/aiecs-kg
Project-URL: Documentation, https://github.com/Howmany-Zeta/aiecs-kg#readme
Project-URL: Bug Tracker, https://github.com/Howmany-Zeta/aiecs-kg/issues
Keywords: knowledge-graph,graph-store,aiecs,rag,entity-linking
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: <3.13,>=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: LICENSE_HEADER.txt
Requires-Dist: pydantic<3.0.0,>=2.11.5
Requires-Dist: pydantic-settings<3.0.0,>=2.9.1
Requires-Dist: python-dotenv<2.0.0,>=1.1.0
Requires-Dist: numpy<3.0.0,>=2.4.1
Requires-Dist: networkx<4.0.0,>=3.0
Requires-Dist: cachetools<6.0.0,>=5.0.0
Requires-Dist: typing-extensions<5.0.0,>=4.13.2
Requires-Dist: pyyaml<7.0.0,>=6.0.2
Requires-Dist: tqdm<5.0.0,>=4.66.0
Provides-Extra: postgres
Requires-Dist: asyncpg<1.0.0,>=0.30.0; extra == "postgres"
Provides-Extra: sqlite
Requires-Dist: aiosqlite<1.0.0,>=0.20.0; extra == "sqlite"
Provides-Extra: neo4j
Requires-Dist: neo4j<6.0.0,>=5.25.0; extra == "neo4j"
Provides-Extra: graph
Requires-Dist: aiecs-kg[neo4j,postgres]; extra == "graph"
Provides-Extra: reasoning
Requires-Dist: lark-parser<0.13.0,>=0.12.0; extra == "reasoning"
Requires-Dist: colorama<1.0.0,>=0.4.6; extra == "reasoning"
Requires-Dist: python-Levenshtein<1.0.0,>=0.25.0; extra == "reasoning"
Provides-Extra: rerank
Requires-Dist: sentence-transformers>=3.2.1; extra == "rerank"
Provides-Extra: builder
Requires-Dist: pandas<3.0.0,>=2.2.0; extra == "builder"
Requires-Dist: openpyxl<4.0.0,>=3.1.0; extra == "builder"
Requires-Dist: pyreadstat<2.0.0,>=1.2.0; extra == "builder"
Requires-Dist: psutil<8.0.0,>=6.0.0; extra == "builder"
Provides-Extra: nlp
Requires-Dist: spacy<4.0.0,>=3.7.0; extra == "nlp"
Provides-Extra: fusion
Requires-Dist: redis<6.0.0,>=5.0.0; extra == "fusion"
Provides-Extra: aiecs
Requires-Dist: aiecs>=1.11.0; extra == "aiecs"
Provides-Extra: dev
Requires-Dist: pytest<9.0.0,>=8.4.2; extra == "dev"
Requires-Dist: pytest-asyncio<2.0.0,>=1.2.0; extra == "dev"
Requires-Dist: pytest-cov<8.0.0,>=7.0.0; extra == "dev"
Requires-Dist: pytest-timeout<3.0.0,>=2.4.0; extra == "dev"
Requires-Dist: mypy<2.0.0,>=1.18.2; extra == "dev"
Requires-Dist: flake8<8.0.0,>=7.3.0; extra == "dev"
Requires-Dist: black<26.0.0,>=25.1.0; extra == "dev"
Requires-Dist: pre-commit<5.0.0,>=4.5.1; extra == "dev"
Requires-Dist: deptry<0.24.0,>=0.23.0; extra == "dev"
Requires-Dist: types-PyYAML>=6.0.0; extra == "dev"
Requires-Dist: aiecs-kg[builder,fusion,neo4j,nlp,postgres,reasoning,rerank,sqlite]; extra == "dev"
Provides-Extra: all
Requires-Dist: aiecs-kg[dev,postgres,reasoning,sqlite]; extra == "all"
Provides-Extra: release
Requires-Dist: build<2.0.0,>=1.2.0; extra == "release"
Requires-Dist: twine<7.0.0,>=5.1.0; extra == "release"
Requires-Dist: packaging<26.0.0,>=24.0; extra == "release"
Dynamic: license-file

# aiecs-kg

Enterprise knowledge graph (L2) for [AIECS](https://github.com/Howmany-Zeta/AI-Execute-Services), split from the monorepo as an optional PyPI package.

## Status

**Alpha 0.9.0a1** — first public PyPI release (`Development Status :: 3 - Alpha`). Core graph store, reasoning (heuristic + Logic DSL), and builder paths are usable; PostgreSQL / Neo4j dual-store and LLM features require optional extras and caller configuration.

See [temporal_kg_memory/KNOWLEDGE_GRAPH_OPTIONAL_PACKAGING.md](temporal_kg_memory/KNOWLEDGE_GRAPH_OPTIONAL_PACKAGING.md) for the full split checklist.

### CI verification scope

GitHub Actions (`pip install -e ".[dev]"`, no external services) validates:

| Area | CI | Requires local / maintainer setup |
|------|-----|-----------------------------------|
| In-memory graph store | Yes | — |
| SQLite backend | Yes | — |
| Reasoning (Logic DSL, orchestrator) | Yes | — |
| Structured builder import | Yes | — |
| LLM injection (mock clients) | Yes | Real LLM keys: manual / nightly |
| PostgreSQL (`[postgres]`) | No (skip) | `KG_POSTGRES_URL` + `.env.test` |
| Neo4j / `pg_neo4j` / GDS (`[graph]`) | No (skip) | `KG_NEO4J_URI` + system Neo4j 5.26+ |
| AIECS integrations (`[aiecs]`) | No (skip) | `pip install aiecs-kg[aiecs]` |

Release gate (tag `v*`): unit tests + `deptry` + `build` + `twine check` (see [scripts/README.md](scripts/README.md)).

## Install

```bash
# Core (in-memory graph store)
pip install -e .

# With backends
pip install -e ".[postgres,sqlite,reasoning]"

# Neo4j graph compute + PostgreSQL dual-store (Phase NG)
pip install -e ".[graph]"          # neo4j + postgres extras
# or: pip install -e ".[neo4j,postgres]"

# Development
pip install -e ".[dev,sqlite]"
```

### Optional extras

| Extra | Installs | LLM / AIECS |
|-------|----------|-------------|
| *(core)* | Graph store, reasoning heuristics | No LLM — pass `llm_client=` / `embedding_client=` yourself |
| `reasoning` | Lark Logic DSL parser | No LLM |
| `builder` | Structured data import (pandas, etc.) | No LLM; `GraphBuilder` accepts injected `embedding_client=` |
| `aiecs` | Declares compatible `aiecs` version | Optional helpers in `aiecs_kg.integrations.aiecs` only (not core imports) |

For LLM usage patterns see [LLM integration](#llm-integration) and [LLM_CLIENT_INJECTION_PLAN.md §7](temporal_kg_memory/LLM_CLIENT_INJECTION_PLAN.md).

Deprecated factory methods (`GraphBuilder.from_config`, `LLMEntityExtractor.from_config`) remain for compatibility but do not resolve AIECS clients in core — use explicit injection or `aiecs_kg.integrations.aiecs`.

### Storage modes (`KG_STORAGE_MODE`)

| Mode | PostgreSQL | Neo4j | Use case |
|------|------------|-------|----------|
| `pg_only` (default) | authority + vector | — | Zero Neo4j regression; Python graph fallback |
| `pg_neo4j` | authority + pgvector RAG | traverse + GDS projection | **Recommended production** embed path |
| `neo4j_only` | — | single store | POC / graph-only dev |

Design: [AIECS_KG_NEO4J_PG_DUAL_STORE_DESIGN.md](temporal_kg_memory/AIECS_KG_NEO4J_PG_DUAL_STORE_DESIGN.md) · ADR: [ADR-004](temporal_kg_memory/adr/ADR-004-neo4j-pg-dual-store.md)

### pg_neo4j quick example

```bash
export KG_STORAGE_MODE=pg_neo4j
export KG_STORAGE_BACKEND=postgresql
export KG_POSTGRES_URL=postgresql://user:pass@localhost:5432/aiecs_knowledge_graph
export KG_NEO4J_URI=bolt://localhost:7687
export KG_NEO4J_USER=neo4j
export KG_NEO4J_PASSWORD=your-password
export KG_NEO4J_DATABASE=aiecs_graph
```

```python
from aiecs_kg import create_graph_store, create_graph_algorithm_service

store = create_graph_store()          # CompositeGraphStore when pg_neo4j
await store.initialize()
algo = create_graph_algorithm_service(graph_store=store)
scores = await algo.pagerank(seed_entity_ids=["entity-a"], top_k=10)
```

See [.env.example](.env.example) for all `KG_*` variables.

## Quick start

```python
from aiecs_kg import create_graph_store, Entity

store = create_graph_store()  # KG_STORAGE_BACKEND=inmemory (default)
await store.initialize()

entity = Entity(id="e1", entity_type="Person", properties={"name": "Alice"})
await store.add_entity(entity)
```

### Reasoning (Phase R0–R2)

Prefer `ReasoningOrchestrator` over `ReasoningEngine` for NL, Logic DSL, and hybrid pipelines:

```python
import asyncio
from aiecs_kg import create_reasoning_orchestrator, ReasoningOrchestrator
from aiecs_kg.application.reasoning import ReasoningPipelineConfig

async def main():
    orchestrator = create_reasoning_orchestrator()  # or ReasoningOrchestrator(store, ...)
    result = await orchestrator.query(
        "Find all people older than 30",
        mode="hybrid",  # nl | logic_dsl | hybrid
        context={"start_entity_id": "alice"},
    )
    print(result.answer, result.evidence_count)

asyncio.run(main())
```

Install Logic DSL support: `pip install -e ".[reasoning]"`. Optional rerank extra: `pip install -e ".[rerank]"`.

## LLM integration

`pip install aiecs-kg` does **not** install or import AIECS. LLM-powered features (entity/relation extraction, NL→DSL, QueryPlan, embeddings) require a caller-provided client via constructor or factory parameters (`llm_client=`, `embedding_client=`).

```python
from aiecs_kg import create_reasoning_orchestrator
from aiecs_kg.ports.llm_client import LLMMessage  # use this, not aiecs.llm.LLMMessage

# Heuristic / retrieval-only — no LLM required
orchestrator = create_reasoning_orchestrator()

# With an injected client (AIECS resolve_llm_client, OpenAI SDK wrapper, etc.)
orchestrator = create_reasoning_orchestrator(llm_client=my_client)
```

All `generate_text` messages in core code use `aiecs_kg.ports.llm_client.LLMMessage`. Clients must implement at least `generate_text` and/or `get_embeddings` (see `LLMClientProtocol`). For a minimal OpenAI SDK example without AIECS, see [LLM_CLIENT_INJECTION_PLAN.md §7.4](temporal_kg_memory/LLM_CLIENT_INJECTION_PLAN.md#74-自定义-client任意-sdk--无需-aiecs).

Optional AIECS convenience helpers (when both packages are installed) live under `aiecs_kg.integrations.aiecs` — not exported from core `__init__.py`.

## Configuration

All settings use `KG_*` environment variables. See [.env.example](.env.example).

```bash
export KG_STORAGE_BACKEND=inmemory   # inmemory | sqlite | postgresql
export KG_ENABLED=true               # consumed by AIECS core (not this package)
```

## Project layout

```
src/aiecs_kg/
├── domain/          # Entity, Relation, schema models
├── application/     # search, reasoning, builder, fusion, …
├── storage/         # GraphStore backends (in-memory, SQLite, Postgres)
├── config.py        # KGSettings / get_kg_settings()
└── factory.py       # create_graph_store()
```

## Tests

```bash
# 1) 依赖（见 .env.test 注释）
pip install -e ".[dev,rerank]"
python -m spacy download en_core_web_sm
# aiecs：若 PyPI 与 dev 解析冲突，改本地可编辑安装（勿与 [aiecs] extra 同时 pip 解析）
pip install -e /path/to/python-middleware-dev

# 2) 环境
set -a && source .env.test && set +a   # KG_USE_AIECS_STUB=false + XAI_API_KEY 等

pytest tests/unit -q
pytest tests/integration/neo4j_graph/ -q   # 需系统 Neo4j 5.26.x + GDS（ADR-004）
```

## Pre-commit

Same hook set as [AI-Execute-Services](https://github.com/Howmany-Zeta/AI-Execute-Services): license header, black, flake8, mypy, and **deptry** (no AIECS-specific schema hooks).

Dependencies are declared only in `pyproject.toml`. CI installs `pip install -e ".[dev]"` with no ad-hoc packages. See `.cursor/rules/dependency-maintenance.mdc`.

```bash
pip install -e ".[dev]"
pre-commit install
pre-commit run --all-files
```

## License

Apache-2.0 — see [License.txt](License.txt).
