Metadata-Version: 2.4
Name: hyper-reason
Version: 0.1.1
Summary: A logical reasoner that uses a knowledge graph as a world model and the IKL logic DSL to beat dense-embedding/RAG precision+recall: ingest documents into a SQLite KG, query/forecast/counterfactual via IKL compiled to SQL, and return D3-visualisable graphs + grounded LLM interpretations with honest refusal. Local developer tool; the only AWS dependency is Bedrock InvokeModel for the Strands agent. Bundles hyper-kg + hyper-gliner.
License: Apache-2.0
Project-URL: Homepage, https://pypi.org/project/hyper-reason/
Keywords: knowledge-graph,infon,ikl,ikris,strands,bedrock,agent,d3,sqlite,ontology,world-model,forecast,sheaf,gnn
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: torch>=2.3
Requires-Dist: tokenizers>=0.19
Requires-Dist: safetensors>=0.4
Requires-Dist: numpy>=1.24
Provides-Extra: hub
Requires-Dist: huggingface_hub>=0.23; extra == "hub"
Provides-Extra: agent
Requires-Dist: strands-agents>=0.1; extra == "agent"
Requires-Dist: boto3>=1.34; extra == "agent"
Provides-Extra: api
Requires-Dist: fastapi>=0.110; extra == "api"
Requires-Dist: uvicorn>=0.29; extra == "api"
Provides-Extra: docs
Requires-Dist: python-docx; extra == "docs"
Requires-Dist: python-pptx; extra == "docs"
Requires-Dist: pymupdf; extra == "docs"
Requires-Dist: pdfplumber; extra == "docs"
Requires-Dist: pillow; extra == "docs"
Provides-Extra: pretty
Requires-Dist: rich>=13.0.0; extra == "pretty"
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"

# hyper-reason

A logical reasoner that uses a **knowledge graph as a world model** and a logic DSL — **IKL** (IKRIS
Knowledge Language) — to overcome the poor precision and recall of research agents built on dense
embeddings and RAG. Facts are stored as a typed graph in **one SQLite file** (the ontology *and* a
trained dynamics model live in that same file, as tables — so you ship a single artifact), queried with
compiled logic instead of vector similarity, and answered with provenance and **honest refusal**.

Beyond looking facts up, it uses the graph to **forecast** market dynamics and run **counterfactuals**
and **multi-player simulations** ("how would regulators vs. demographics vs. competitors react") — and
every predicted outcome separates *what the model predicts* (plausibility) from *what the data supports*
(grounded-subgraph evidence), so an extrapolation is never dressed up as a fact.

Seven verbs. Usable as a **CLI** (easiest for testing and day-to-day use) and as a local **HTTP API**.

---

## The endpoints

> The `ontology.json` is mirrored in a SQLite table (and a trained dynamics model is stored as a blob
> table), so the whole knowledge graph **and** its ontology **and** its world-model ship as **one file**.

### `Ingest(file) -> str`  ("Success" / "Fail")
Converts documents + tables + images → text → infons (facts) via **GLiNER** (`cp500/infon-extract`)
**+ SPLADE**, and appends them to the knowledge graph in SQLite.

### `Query(str) -> (str, json)`  (agent response, D3-compatible graph)
Uses **Strands** to understand *who* is asking (the persona / valence) and designs the **IKL** query
to match. The agent writes IKL — extended with the causal `do()`/`cf()` interventions in an agentic
refine loop via a dedicated prompt-template tool. The IKL is compiled to **SQL** and run; the result
becomes a **D3 graph**, and a Strands agent interprets it back into natural language.

### `Optimise(text | folder) -> (json, float, float)`  (ontology, precision, recall)
Pass a file or folder of domain-specific text. The Strands agent optimises the `ontology.json` for the
**precision + recall** of facts stored on the SQLite knowledge graph, and writes the tuned ontology
back into the file's ontology table. (Changing the ontology's *structure* marks any trained world-model
**stale** — see `train`.)

### `Merge(target.sqlite, folder_of_sqlite) -> str`  ("Success" / "Fail")
Thousands of workers can each generate a SQLite file; this merges them all — **including the ontology
tables** — into one, deduping by stable id so it's idempotent.

### `Export(directory) -> str`  (path to the written .sqlite)
Exports the working knowledge graph — **including the ontology table and any trained model** — as a
single self-contained `.sqlite` file.

### `Train() -> TrainReport`  (the world-model)
Trains a **Neural Sheaf Diffusion GNN** on a synthetic, deterministically-generated temporal world
(feature-adoption diffusion, sentiment contagion, competitive reaction, regulatory shocks) keyed to the
file's ontology, then persists the checkpoint (a few KB) **into the same `.db`**. The report includes
held-out metrics and a baseline comparison so you can see the sheaf *earns its keep* (beats a
frequency-prior / no-diffusion baseline), plus a calibration curve for the plausibility numbers.

### `Forecast(str) -> (ForecastResult, json)`  (projected world graph)
Uses the graph as a **world model** to answer a what-if / counterfactual / multi-player question. A
forecast *constructs a new graph* — the projected "what-if" world — and returns it as D3, where every
node and edge is tagged by its support: `grounded` (backed by real graph evidence), `model-only`
(extrapolation, unverified), or `projected` (the what-if edge itself). Outcomes form a ranked
distribution that sums to ~1 **with an explicit `refusal_mass`** for the futures it can't enumerate —
each outcome carrying a **plausibility** *and* a separate **data_support** so trusted and inferred parts
of the future are visually distinguishable. Falls back to a grounded comparable-transfer heuristic when
no model is trained.

---

## Install

```bash
cd hyper-reason
python3 -m venv .venv && source .venv/bin/activate

# vendored upstreams first (order matters: kg depends on gliner), then hyper-reason
pip install -e packages/hyper-gliner
pip install -e packages/hyper-kg
pip install -e ".[agent,api,docs]"      # agent=Strands/Bedrock, api=FastAPI, docs=office/PDF/image
```

`[docs]` enables the documents + tables + images path; `[agent]` enables the Strands agent on Bedrock;
`[api]` enables the local HTTP server. The core install (`pip install -e .`) is enough to ingest text,
run IKL→SQL, **train the world-model, and forecast** — all with no AWS at all (only `query` and
`optimise` reach Bedrock, and only for the LLM phrasing/proposal steps). `train`/`forecast` are CPU-only
and use `torch`, which `hyper-gliner` already pulls in.

> **First run downloads the model.** The first `ingest` (or `query`) fetches the GLiNER extraction
> model `cp500/infon-extract` (~a few hundred MB) from Hugging Face and prints a one-time notice. It is
> cached locally, so every run after that starts immediately. Set `HYPER_REASON_QUIET=1` to silence the
> notice; point `--db` aside and the download is shared via the standard HF cache (`~/.cache/huggingface`).

---

## CLI (recommended)

The verbs map one-to-one to subcommands. Every command works on a single `.db` file
(`--db`, default `./knowledge.db`).

```bash
hyper-reason ingest   --db knowledge.db  path/to/report.pdf        # -> Success | Fail: <reason>
hyper-reason query    --db knowledge.db  "How do owners feel about fast charging?"
hyper-reason optimise --db knowledge.db  ./domain_texts/           # -> ontology + precision + recall
hyper-reason merge    knowledge.db       ./worker_outputs/         # fold a folder of shards -> Success
hyper-reason export   --db knowledge.db  ./out/                    # -> ./out/knowledge.sqlite
hyper-reason train    --db knowledge.db  [--epochs 40 --scale tiny] # train the world-model into the .db
hyper-reason forecast --db knowledge.db  "what if Hyundai ships solid-state to the mass market?"
```

`query` prints the natural-language agent response and the D3 graph JSON (use `--json` for the graph
only, `--text` for the interpretation only). `forecast` prints the ranked outcome distribution and the
**projected what-if world** as a D3 graph (`--json` for the graph only); `--horizon N` projects further
ahead, `--top-k K` bounds the distinct outcomes.

## HTTP API (optional, local)

```python
from hyper_reason.api import run     # needs the [api] extra
run()                                # serves the endpoints on http://127.0.0.1:8011
```

`POST /v1/ingest`, `/v1/query`, `/v1/optimise`, `/v1/merge`, `/v1/export` (the core five over HTTP).

---

## AWS credentials (Bedrock)

`Query` and `Optimise` use the Strands agent on **Amazon Bedrock**, authenticated with **your own**
AWS credentials (standard chain: env vars / `~/.aws` profile / SSO). hyper-reason creates no AWS
resources and stores no credentials.

If Bedrock can't be reached, the tool **stops with a clear, actionable message** rather than a stack
trace — telling you to **refresh or set up your local AWS credentials**, e.g.:

```
hyper-reason: cannot reach Amazon Bedrock — no AWS credentials resolved.
  Refresh or configure your local AWS credentials, then retry. For example:
    export AWS_PROFILE=<your-profile>     # or aws sso login --profile <your-profile>
    export AWS_REGION=us-east-1           # a region with Bedrock + Claude access
```

`Ingest`, `Merge`, and `Export` need no AWS and run fully offline.

---

## One file, by design

Everything for a knowledge graph — the nodes, edges, recall index, the ontology, **and** a trained
world-model — lives in a single SQLite file. `Merge` unions those files (ontology included); `Export`
snapshots one. That is the whole shipping story: hand someone a `.sqlite` and they have the graph, the
schema that built it, and the model that forecasts over it.

Built on the vendored, unmodified packages `hyper-kg` (the typed KG store + IKL evaluator) and
`hyper-gliner` (the GLiNER infon extractor), both copied into `packages/` so the repo is fully
self-contained (no external workspace, no PyPI). See `docs/API_5_endpoints.md` for the core-verb spec,
`docs/DESIGN_world_model_dynamics.md` for the forecast/sheaf-GNN design, and `docs/CONTRACTS.md` for the
internal shapes.

## License

Apache-2.0.
