@littlebigbrain/client 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,127 @@
1
+ # @lbb/client
2
+
3
+ TypeScript client for the [Little Big Brain](../../README.md) graph + hybrid search HTTP
4
+ API. Request and response types are generated from the committed
5
+ [`contracts/openapi.json`](../../contracts/openapi.json) (the single source of
6
+ truth, derived from the Rust `lbb-api` types); the client itself is a thin,
7
+ dependency-free wrapper over the platform `fetch`.
8
+
9
+ ```sh
10
+ npm install @lbb/client
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import { LbbClient, LbbError } from "@lbb/client";
17
+
18
+ const lbb = new LbbClient({
19
+ baseUrl: "https://db.eu.littlebigbrain.com",
20
+ apiKey: process.env.LBB_API_KEY, // lbb_sk_test_… or lbb_sk_live_…
21
+ });
22
+
23
+ await lbb.graph("main").facts.create({
24
+ triplets: [
25
+ {
26
+ source: { type: "SERVICE", name: "auth-service" },
27
+ relation: "WRITES_TO",
28
+ target: { type: "DATABASE", name: "user-db" },
29
+ confidence: 0.93,
30
+ evidence: "auth-service writes identity records to user-db",
31
+ },
32
+ ],
33
+ }, {
34
+ idempotencyKey: "import-2026-06-13",
35
+ });
36
+
37
+ await lbb.indexes.run({ wait: true });
38
+
39
+ const results = await lbb.search.hybrid("which systems store customer identity data", {
40
+ topK: 5,
41
+ source: "persisted",
42
+ consistency: "strong",
43
+ targets: ["entities", "assertions"],
44
+ });
45
+ for (const assertion of results.assertions ?? []) {
46
+ console.log(assertion.relation?.name, assertion.score);
47
+ }
48
+ ```
49
+
50
+ Use `client.graph("name")` to scope graph writes and `client.rawRequest(...)`
51
+ when you need response metadata (`requestId`, `version`, headers). Every method
52
+ returns parsed JSON and throws `LbbError` with `status`, `type`, `code`,
53
+ `message`, `param`, `requestId`, and `docUrl` on a non-2xx response.
54
+
55
+ ## Methods
56
+
57
+ | Area | Methods |
58
+ | --- | --- |
59
+ | Write | `graph("main").facts.create` |
60
+ | Search | `search.hybrid`, `search.multi`, `search.fullText`, `search.vector` |
61
+ | Search feedback (training data) | `searchFeedback` (grade results 3/1/0 → customer qrels), `searchFeedbackExport` |
62
+ | Traversal | `traverse`, `semanticTraverse` |
63
+ | Temporal / lineage / shapes | `currentState`, `history`, `why`, `shacl` |
64
+ | SPARQL | `sparqlRows`, `sparql` (SELECT/ASK/aggregate; GROUP BY entity, property, or date bucket), `sparqlText`, `analytics` |
65
+ | Ontology | `ontologyView` (add `{ counts: true }` for per-relation `edge_count`), `ontologySearch`, `ontologyResolve`, `ontologyDefine` |
66
+ | Index lifecycle | `indexes.run`, `indexes.build`, `indexes.delta`, `indexes.gc`, `compact` |
67
+ | Inspection | `entities.list`, `entities.filterByAttributes`, `status`, `metadata`, `summary` |
68
+ | Schema activation | `schema.view`, `schema.preview`, `schema.publish`, `schema.audit` |
69
+ | Database admin | `adminCreateStack`, `adminStack`, `adminRotateStackKey`, `adminDeleteStack` |
70
+
71
+ Request/response shapes are exported as `Schemas["TypeName"]` (e.g.
72
+ `Schemas["SemanticGraphSearchRequest"]`); the raw generated `components`,
73
+ `paths`, and `operations` are exported too.
74
+
75
+ ## SPARQL
76
+
77
+ `client.sparqlRows(...)` runs a SPARQL 1.1 text query (SELECT or ASK) and
78
+ returns parsed results, so you never have to `JSON.parse` the results string or
79
+ zip `head.vars` with binding values yourself:
80
+
81
+ ```ts
82
+ const { vars, rows } = await client.sparqlRows({
83
+ query: `SELECT ?service ?db WHERE {
84
+ ?service <https://littlebigbrain.com/r/writes_to> ?db
85
+ } LIMIT 10`,
86
+ reason: true, // optional: fold in rule-derived edges
87
+ });
88
+ for (const row of rows) console.log(row.service, "->", row.db);
89
+
90
+ const exists = (await client.sparqlRows({ query: "ASK { ?s ?p ?o }" })).boolean;
91
+ ```
92
+
93
+ For app code that already has relation patterns but just needs typed attribute
94
+ predicates, `client.entities.filterByAttributes(...)` builds the structured
95
+ SPARQL filter body without exposing RDF property IRIs:
96
+
97
+ ```ts
98
+ await client.entities.filterByAttributes({
99
+ patterns: [{ subject: { var: "service" }, predicate: "WRITES_TO", object: { var: "db" } }],
100
+ where: [{ field: "slo", op: "ge", value: 0.99 }, { var: "db", field: "tier", value: "prod" }],
101
+ select: ["service"],
102
+ });
103
+ ```
104
+
105
+ `sparqlRows` returns `{ vars, boolean, bindings, rows }`: `rows` is the bindings
106
+ flattened to `{ variable: lexicalValue }`, `bindings` keeps the raw typed term
107
+ objects, and `boolean` is the ASK answer (or `null` for a SELECT). `client.sparqlText(...)`
108
+ returns the unparsed envelope, and the standalone `parseSparqlResults(response)`
109
+ helper (also exported) parses it. For the structured BGP form use
110
+ `client.sparql(body)` (`SparqlSelectRequest`).
111
+
112
+ A standalone stack also serves the **native SPARQL 1.1 Protocol** at `/sparql`
113
+ (`GET ?query=`, `POST` form or `application/sparql-query` body,
114
+ `Accept`-negotiated JSON/XML/CSV/TSV) for off-the-shelf SPARQL clients (YASGUI,
115
+ Protégé); `sparqlRows` returns parsed JSON rows for in-process use.
116
+
117
+ ## Develop
118
+
119
+ ```sh
120
+ npm install
121
+ npm run generate # regenerate src/schema.ts from ../../contracts/openapi.json
122
+ npm run build # tsc -> dist/
123
+ npm test # build + node:test (mocked fetch)
124
+ ```
125
+
126
+ `runtime`: any environment with a global `fetch` (Node 18+, browsers, edge
127
+ workers), or pass your own via the `fetch` option.