@odla-ai/kg 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # @odla-ai/kg
2
+
3
+ An ontology-driven **knowledge-graph builder**. Pluggable source connectors pull
4
+ from the web and data feeds, an LLM extracts entities + relationships against a
5
+ **config-as-data ontology**, and a provenance-preserving graph writer persists
6
+ the result into [odla-db](https://www.npmjs.com/package/@odla-ai/db).
7
+
8
+ The library is host-agnostic: it runs in Cloudflare Workers, Node, or tests —
9
+ the host supplies the database client, LLM keys, and a KV-like store. For a
10
+ complete deployable consumer (workflows, hourly cron, HTTP API, viewer UI), see
11
+ `examples/kg-demo` in the [odla-ai monorepo](https://github.com/odla-ai/odla-ai).
12
+
13
+ ## Architecture
14
+
15
+ ```
16
+ Connector ──RawItem[]──▶ Extraction ──GraphFragment──▶ writeFragment ──Op[]──▶ odla-db
17
+ (how data (LLM forced-tool (ontology-typed (Lookup upserts +
18
+ was acquired) OR pure mapper) nodes + edges) links, idempotent)
19
+ ```
20
+
21
+ - **`RawItem`** — a connector emits either `text` (→ LLM extraction) or a
22
+ ready-made `fragment` (structured feeds bypass the LLM).
23
+ - **`GraphFragment`** — ontology-typed `nodes[]` + `edges[]`; the single shape
24
+ the writer consumes, whatever produced it.
25
+ - **`Ontology`** — data, not code. It compiles to the odla-db schema
26
+ (`toSerializedSchema`), the writer's natural-key + merge-rule maps
27
+ (`naturalKeysOf`, `mergeRulesOf`, `humanAttrsOf`), and by convention the
28
+ extractor's tool schema.
29
+
30
+ Add a source → implement `SourceConnector` + one registry line. Add an
31
+ entity/edge type → edit the ontology data. Neither touches the pipeline.
32
+
33
+ ## Usage
34
+
35
+ ```ts
36
+ import { init } from "@odla-ai/db";
37
+ import {
38
+ Store, getProvider, makeContext, ingestFresh, writeFragment,
39
+ toSerializedSchema, type Ontology, type PipelineDeps,
40
+ } from "@odla-ai/kg";
41
+
42
+ // 1. Your ontology is data (see the OSINT example in examples/kg-demo).
43
+ const ontology: Ontology = { entities: { /* … */ }, edges: { /* … */ } };
44
+
45
+ // 2. Wire the host services once.
46
+ const db = init({ appId, adminToken, endpoint });
47
+ const provider = getProvider({ LLM_PROVIDER: "claude", ANTHROPIC_API_KEY: key });
48
+ const deps: PipelineDeps = { db, provider, ontology, extract: myExtractor, store: new Store(kv) };
49
+
50
+ // 3. Run items through the shared pipeline (or call writeFragment directly).
51
+ await ingestFresh(step, deps, freshItems, "ingest");
52
+ ```
53
+
54
+ Key seams the host supplies:
55
+
56
+ - **`PipelineDeps`** — db (`AdminDb`), LLM `Provider`, the ontology, the
57
+ extractor (your domain craft), and a `Store` over any `KVLike`.
58
+ - **`ContextConfig`** (→ `makeContext`) — what connectors see: ontology, lazy
59
+ provider, named secrets.
60
+ - **`StepLike`** — a structural view of Cloudflare's `WorkflowStep`
61
+ (`asStepLike(step)`); any `do(name, cfg?, fn)` runner works, including a
62
+ plain inline runner in tests.
63
+
64
+ ## Built-in connectors
65
+
66
+ `rss`, `url`, `gdelt` (text → LLM extraction) · `fred`, `edgar` (structured →
67
+ straight to the writer) · `web-search` (LLM web-search discovery) · `gov-data`
68
+ (template proving a new source needs no pipeline change).
69
+
70
+ ## Provenance & merging
71
+
72
+ `writeFragment` reads existing nodes by natural key (one batched query), merges
73
+ scalar attrs per the ontology's rules (`replace` / `prefer` / `earliest` /
74
+ `latest`), never writes `human`-owned attrs, and commits nodes-then-links in a
75
+ single idempotent transaction (deterministic `mutationId`).