narrative-graph 0.1.2

Turn prose into candidate relational facts — entity detection, relation labeling, confidence scoring, entirely local.
Documentation
# Integration

## Installing

```bash
npm install narrative-graph
```

The package ships a single native binding built via N-API 3 (`napi` /
`napi-derive` in `Cargo.toml`), a CommonJS entry point, an ESM entry point,
and hand-written TypeScript declarations regenerated from the Rust types via
`ts-rs` (`bindings/*.ts`, folded into `index.d.ts`).

```json
{
  "main": "index.js",
  "exports": {
    ".": {
      "types": "./index.d.ts",
      "import": "./index.mjs",
      "require": "./index.js"
    }
  }
}
```

## Node (CommonJS)

```js
const { extractCandidateTriplesNapi } = require('narrative-graph')

const candidates = extractCandidateTriplesNapi("Elena is Marco's sister.")
// [{ subject: 'elena', relation: 'sister_of', object: 'marco',
//    confidence: 0.85, span: [0, 23], rule: 'possessive-sister-pattern' }]
```

## Node (ESM)

```js
import { extractCandidateTriplesNapi } from 'narrative-graph'

const candidates = extractCandidateTriplesNapi('Marco mentors Dev.')
```

## TypeScript

`index.d.ts` declares the single export and its option/result types:

```ts
import { extractCandidateTriplesNapi, NapiOptions, NapiTripleCandidate } from 'narrative-graph'

const opts: NapiOptions = {
  aliases: { 'the detective': 'marcus' },
  minConfidence: 0.7,
  ontology: { mentors: 'mentorship' },
}

const candidates: NapiTripleCandidate[] = extractCandidateTriplesNapi(text, opts)
```

`opts` is optional — omit it, or pass `undefined`/`null`, to run with
defaults (no aliases, no confidence floor, no ontology remapping).

### Options

| Field | Type | Default | Effect |
|---|---|---|---|
| `aliases` | `Record<string, string>` | `{}` | Surface form → canonical entity name. Any mention matching a key resolves to the mapped value. |
| `minConfidence` | `number` (0.0–1.0) | `0.0` (all candidates) | Candidates below this score are filtered out. Passing a value outside `[0.0, 1.0]` throws. |
| `ontology` | `Record<string, string>` | `{}` | Recognized relation name → caller-supplied vocabulary. Relations not present in the map pass through with their heuristic default name. |

### Result shape

Each `NapiTripleCandidate`:

| Field | Type | Meaning |
|---|---|---|
| `subject` | `string` | Normalized subject entity (lowercase, spaces → underscores) |
| `relation` | `string` | Relation type, after ontology remapping if applicable |
| `object` | `string` | Normalized object entity |
| `confidence` | `number` | 0.0–1.0 |
| `span` | `number[]` | `[start, end)` byte range in the input text |
| `rule` | `string` | Name of the extraction rule that produced this candidate |

### Error handling

The only error the current pipeline raises is an out-of-range
`minConfidence`. It surfaces as a thrown `Error` (Rust's
`napi::Status::GenericFailure`) with a message containing "confidence
threshold":

```js
try {
  extractCandidateTriplesNapi(text, { minConfidence: 1.5 })
} catch (err) {
  // err.message: "Confidence threshold must be between 0.0 and 1.0, got 1.5"
}
```

## Rust

```toml
[dependencies]
narrative-graph = "0.1"
```

```rust
use narrative_graph::{extract_candidate_triples, Options};

let candidates = extract_candidate_triples(
    "Elena is Marco's sister.",
    &Options::default(),
)?;
```

## CLI

```bash
cargo install narrative-graph --features cli
narrative-graph extract chapter.txt --min-confidence 0.6 --format json
```

Reads a file (or `-` for stdin) and writes candidates as `text` (default) or
`json` to stdout — useful for a shell pipeline or a CI check without
embedding the library.

## Feeding a downstream store

`TripleCandidate` / `NapiTripleCandidate` are plain `(subject, relation,
object)` facts with no opinion on storage. The shape lines up directly with
a relational-fact store's write API — for example
[`holographic-memory`](https://github.com/writerslogic/holographic-memory)'s
`memorizeTriplet(id, subject, relation, object)`:

```js
const { extractCandidateTriplesNapi } = require('narrative-graph')
const { HolographicMemorySystem } = require('holographic-memory')

const hms = new HolographicMemorySystem(16384, './storage', { meaningEnabled: true })

const candidates = extractCandidateTriplesNapi(chapterText, { minConfidence: 0.7 })
for (const [i, c] of candidates.entries()) {
  await hms.memorizeTriplet(`fact-${i}`, c.subject, c.relation, c.object)
}
```

narrative-graph does not depend on `holographic-memory`, or on any store —
this is one integration pattern, not a requirement. Filter on `confidence`
before writing, and keep `span`/`rule` alongside the fact in your own store
if you need to show provenance or support later correction.