@littlebigbrain/client 0.4.2 → 0.4.3
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 +59 -127
- package/dist/namespaces.d.ts +1 -0
- package/dist/namespaces.js +3 -0
- package/dist/schema.d.ts +52 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,169 +1,101 @@
|
|
|
1
1
|
# @littlebigbrain/client
|
|
2
2
|
|
|
3
|
-
TypeScript client for
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
truth, derived from the Rust `lbb-api` types); the client itself is a thin,
|
|
7
|
-
dependency-free wrapper over the platform `fetch`.
|
|
3
|
+
Typed TypeScript client for little big brain: ingest, BM25/vector/graph index,
|
|
4
|
+
authorized hybrid search, traversal, ontology, feedback, and training jobs.
|
|
5
|
+
Runs on Node 18+, browsers, and edge workers using the platform `fetch`.
|
|
8
6
|
|
|
9
7
|
```sh
|
|
10
8
|
npm install @littlebigbrain/client
|
|
11
9
|
```
|
|
12
10
|
|
|
13
|
-
##
|
|
11
|
+
## Five-minute start
|
|
14
12
|
|
|
15
13
|
```ts
|
|
16
|
-
import { LbbClient
|
|
14
|
+
import { LbbClient } from "@littlebigbrain/client";
|
|
17
15
|
|
|
18
16
|
const lbb = new LbbClient({
|
|
19
17
|
baseUrl: "https://db.eu.littlebigbrain.com",
|
|
20
|
-
apiKey: process.env.LBB_API_KEY,
|
|
18
|
+
apiKey: process.env.LBB_API_KEY,
|
|
21
19
|
});
|
|
22
|
-
|
|
23
20
|
const graph = lbb.graph("main");
|
|
24
21
|
|
|
25
22
|
await graph.facts.create({
|
|
26
|
-
triplets: [
|
|
27
|
-
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
}, {
|
|
36
|
-
idempotencyKey: "import-2026-06-13",
|
|
37
|
-
});
|
|
23
|
+
triplets: [{
|
|
24
|
+
source: { type: "CONCEPT", name: "policy-42" },
|
|
25
|
+
relation: "RELATED_TO",
|
|
26
|
+
target: { type: "CONCEPT", name: "seven-year retention" },
|
|
27
|
+
evidence: "Customer records are retained for seven years.",
|
|
28
|
+
}],
|
|
29
|
+
}, { idempotencyKey: "policy-42-v1" });
|
|
38
30
|
|
|
39
31
|
await graph.indexes.run({ wait: true });
|
|
40
32
|
|
|
41
|
-
const results = await graph.search.hybrid(
|
|
42
|
-
|
|
43
|
-
source: "persisted",
|
|
44
|
-
|
|
45
|
-
targets: ["entities", "assertions"],
|
|
46
|
-
});
|
|
47
|
-
for (const assertion of results.assertions ?? []) {
|
|
48
|
-
console.log(assertion.relation?.name, assertion.score);
|
|
49
|
-
}
|
|
33
|
+
const results = await graph.search.hybrid(
|
|
34
|
+
"How long are customer records retained?",
|
|
35
|
+
{ topK: 10, source: "persisted", consistency: "strong" },
|
|
36
|
+
);
|
|
50
37
|
```
|
|
51
38
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
`message`, `param`, `requestId`, and `docUrl` on a non-2xx response.
|
|
39
|
+
Methods return parsed JSON and throw `LbbError` on non-2xx responses. Safe
|
|
40
|
+
reads and idempotency-keyed writes retry transient failures and honor
|
|
41
|
+
`Retry-After`. Keep live stack keys on the server, never in browser bundles.
|
|
56
42
|
|
|
57
|
-
|
|
58
|
-
disables it). Safe reads and idempotency-keyed writes retry `429`/`5xx` and
|
|
59
|
-
network failures up to twice, honoring `Retry-After` with a one-minute cap.
|
|
60
|
-
Bulk NDJSON and RDF imports receive an idempotency key automatically unless you
|
|
61
|
-
provide one explicitly. The preferred namespaced surface accepts the same final
|
|
62
|
-
request options everywhere: `timeoutMs`, `maxRetries`, `signal`, `headers`, and
|
|
63
|
-
`idempotencyKey` for mutations.
|
|
43
|
+
## Enterprise search integrations
|
|
64
44
|
|
|
65
|
-
|
|
45
|
+
Keep the host product's users, connectors, tasks, and cursors in its existing
|
|
46
|
+
database. Put searchable documents, passages, facts, embeddings, indexes,
|
|
47
|
+
feedback, and model runs in little big brain:
|
|
66
48
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
49
|
+
1. Give every document/chunk/passage a stable external key.
|
|
50
|
+
2. Bulk-import content, provenance, and native ACL/tag/project sets.
|
|
51
|
+
3. Configure managed embeddings; build ANN, BM25, and adjacency once per batch.
|
|
52
|
+
4. Filter by ACL inside the search request before ranking and return projected
|
|
53
|
+
fields on the ranked hits.
|
|
54
|
+
5. Grade cited results, reconnect to durable trainer jobs, and require a
|
|
55
|
+
held-out quality plus latency gate before promotion.
|
|
71
56
|
|
|
72
|
-
|
|
73
|
-
|
|
57
|
+
The [enterprise-search integration guide](https://docs.littlebigbrain.com/guides/enterprise-search/)
|
|
58
|
+
contains the graph model, migration sequence, and acceptance tests.
|
|
74
59
|
|
|
75
|
-
|
|
76
|
-
const ontology = await graph.ontology.view({ counts: true });
|
|
77
|
-
const rows = await graph.query.sparql({ query: "SELECT ?s WHERE { ?s ?p ?o }" });
|
|
60
|
+
## Main surface
|
|
78
61
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
62
|
+
```ts
|
|
63
|
+
graph.facts.create(...)
|
|
64
|
+
graph.facts.import(...)
|
|
65
|
+
graph.search.hybrid(...)
|
|
66
|
+
graph.entities.iterate(...)
|
|
67
|
+
graph.context.ask(...)
|
|
68
|
+
graph.ontology.view(...)
|
|
69
|
+
graph.query.sparql(...)
|
|
70
|
+
graph.schema.audit(...)
|
|
82
71
|
```
|
|
83
72
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
fires once for the final response; neither event contains bodies or
|
|
90
|
-
credentials. `rawRequest(...)` additionally reports `attempts`, `retryCount`,
|
|
91
|
-
and `elapsedMs`.
|
|
92
|
-
|
|
93
|
-
## Methods
|
|
94
|
-
|
|
95
|
-
| Area | Methods |
|
|
96
|
-
| --- | --- |
|
|
97
|
-
| Write | `graph("main").facts.create` |
|
|
98
|
-
| Managed embeddings | `graph("main").embeddingConfig`, `graph("main").setEmbeddingConfig`, `graph("main").backfillEmbeddings`, `graph("main").promoteEmbedding` |
|
|
99
|
-
| Search | `search.hybrid`, `search.multi`, `search.fullText`, `search.vector` |
|
|
100
|
-
| Context substrate | `context.ask`, `context.suggest`, `context.resolve`, `context.decode`, `context.groundability` |
|
|
101
|
-
| Search feedback (training data) | `search.feedback`, `search.feedbackExport` |
|
|
102
|
-
| Traversal | `traverse`, `semanticTraverse` |
|
|
103
|
-
| Temporal / lineage / shapes | `currentState`, `history`, `why`, `shacl` |
|
|
104
|
-
| Query | `query.sparql`, `query.structured`, `query.analytics`, `query.shacl`, `query.infer`, `query.premises` |
|
|
105
|
-
| Ontology | `ontology.view`, `ontology.conformance`, `ontology.search`, `ontology.resolve`, `ontology.define`, `ontology.evolve`, `ontology.induce` |
|
|
106
|
-
| Index lifecycle | `indexes.run`, `indexes.build`, `indexes.delta`, `indexes.gc`, `compact` |
|
|
107
|
-
| Inspection | `entities.list`, `entities.filterByAttributes`, `status`, `metadata`, `summary` |
|
|
108
|
-
| Schema activation | `schema.view`, `schema.preview`, `schema.publish`, `schema.audit` |
|
|
109
|
-
|
|
110
|
-
Common request/response shapes have direct imports such as `SearchRequest`,
|
|
111
|
-
`SearchResponse`, `Entity`, `GraphSummary`, `CommitRequest`, `AskResponse`, and
|
|
112
|
-
`SchemaView`. Every generated shape remains available as `Schemas["TypeName"]`;
|
|
113
|
-
the raw `components`, `paths`, and `operations` are exported too.
|
|
114
|
-
|
|
115
|
-
## SPARQL
|
|
73
|
+
Other focused methods cover managed embeddings, full-text/vector search,
|
|
74
|
+
multi-query fusion, traversal, temporal state/history, SHACL, ontology
|
|
75
|
+
evolution, feedback, indexing, and graph inspection. Request/response types are
|
|
76
|
+
generated from `contracts/openapi.json`; common aliases and the complete
|
|
77
|
+
`Schemas` map are exported from the package.
|
|
116
78
|
|
|
117
|
-
`
|
|
118
|
-
|
|
119
|
-
zip `head.vars` with binding values yourself:
|
|
79
|
+
Use `rawRequest()` when you need response headers, request ID, retry count, or
|
|
80
|
+
elapsed time. `onRequest` and `onResponse` provide body-free instrumentation.
|
|
120
81
|
|
|
121
|
-
|
|
122
|
-
const { vars, rows } = await client.sparqlRows({
|
|
123
|
-
query: `SELECT ?service ?db WHERE {
|
|
124
|
-
?service <https://littlebigbrain.com/r/writes_to> ?db
|
|
125
|
-
} LIMIT 10`,
|
|
126
|
-
reason: true, // optional: fold in rule-derived edges
|
|
127
|
-
});
|
|
128
|
-
for (const row of rows) console.log(row.service, "->", row.db);
|
|
129
|
-
|
|
130
|
-
const exists = (await client.sparqlRows({ query: "ASK { ?s ?p ?o }" })).boolean;
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
For app code that already has relation patterns but just needs typed attribute
|
|
134
|
-
predicates, `client.entities.filterByAttributes(...)` builds the structured
|
|
135
|
-
SPARQL filter body without exposing RDF property IRIs:
|
|
82
|
+
## SPARQL
|
|
136
83
|
|
|
137
84
|
```ts
|
|
138
|
-
await
|
|
139
|
-
|
|
140
|
-
where: [{ field: "slo", op: "ge", value: 0.99 }, { var: "db", field: "tier", value: "prod" }],
|
|
141
|
-
select: ["service"],
|
|
85
|
+
const { rows } = await lbb.sparqlRows({
|
|
86
|
+
query: `SELECT ?doc WHERE { ?doc ?p ?o } LIMIT 10`,
|
|
142
87
|
});
|
|
143
88
|
```
|
|
144
89
|
|
|
145
|
-
`sparqlRows`
|
|
146
|
-
|
|
147
|
-
objects, and `boolean` is the ASK answer (or `null` for a SELECT). `client.sparqlText(...)`
|
|
148
|
-
returns the unparsed envelope, and the standalone `parseSparqlResults(response)`
|
|
149
|
-
helper (also exported) parses it. For the structured BGP form use
|
|
150
|
-
`client.sparql(body)` (`SparqlSelectRequest`).
|
|
151
|
-
|
|
152
|
-
A standalone stack also serves the **native SPARQL 1.1 Protocol** at `/sparql`
|
|
153
|
-
(`GET ?query=`, `POST` form or `application/sparql-query` body,
|
|
154
|
-
`Accept`-negotiated JSON/XML/CSV/TSV) for off-the-shelf SPARQL clients (YASGUI,
|
|
155
|
-
Protégé); `sparqlRows` returns parsed JSON rows for in-process use.
|
|
90
|
+
`sparqlRows` parses SELECT/ASK results. The native SPARQL 1.1 Protocol is also
|
|
91
|
+
available at `/sparql` for standard RDF clients.
|
|
156
92
|
|
|
157
93
|
## Develop
|
|
158
94
|
|
|
159
95
|
```sh
|
|
160
96
|
npm install
|
|
161
|
-
npm run generate
|
|
162
|
-
npm run
|
|
163
|
-
npm test
|
|
164
|
-
npm run
|
|
165
|
-
npm run pack:check # exact tarball: publint + ATTW
|
|
97
|
+
npm run generate
|
|
98
|
+
npm run typecheck
|
|
99
|
+
npm test
|
|
100
|
+
npm run pack:check
|
|
166
101
|
```
|
|
167
|
-
|
|
168
|
-
`runtime`: any environment with a global `fetch` (Node 18+, browsers, edge
|
|
169
|
-
workers), or pass your own via the `fetch` option.
|
package/dist/namespaces.d.ts
CHANGED
|
@@ -77,6 +77,7 @@ export declare class SearchNamespace {
|
|
|
77
77
|
multi(body: Schemas["HybridMultiSearchRequest"], opts?: CallOptions): Promise<Schemas["HybridMultiSearchResponse"]>;
|
|
78
78
|
feedback(body: Schemas["SearchFeedbackRequest"], opts?: CallOptions): Promise<Schemas["SearchFeedbackResponse"]>;
|
|
79
79
|
feedbackExport(opts?: CallOptions): Promise<Schemas["SearchFeedbackExportResponse"]>;
|
|
80
|
+
feedbackSummary(opts?: CallOptions): Promise<Schemas["SearchFeedbackSummaryResponse"]>;
|
|
80
81
|
fullText(body: Schemas["FullTextSearchRequest"], opts?: CallOptions): Promise<Schemas["FullTextSearchResponse"]>;
|
|
81
82
|
vector(body: Schemas["EmbeddingSearchRequest"], opts?: CallOptions): Promise<Schemas["EmbeddingSearchResponse"]>;
|
|
82
83
|
}
|
package/dist/namespaces.js
CHANGED
|
@@ -184,6 +184,9 @@ export class SearchNamespace {
|
|
|
184
184
|
feedbackExport(opts = {}) {
|
|
185
185
|
return this.client.request("GET", "/v1/search/feedback/export", opts);
|
|
186
186
|
}
|
|
187
|
+
feedbackSummary(opts = {}) {
|
|
188
|
+
return this.client.request("GET", "/v1/search/feedback/summary", opts);
|
|
189
|
+
}
|
|
187
190
|
fullText(body, opts = {}) {
|
|
188
191
|
return this.client.request("POST", "/v1/search/full-text", {
|
|
189
192
|
...opts,
|
package/dist/schema.d.ts
CHANGED
|
@@ -5904,6 +5904,10 @@ export interface components {
|
|
|
5904
5904
|
* idempotent replays do not advance it and retractions do.
|
|
5905
5905
|
*/
|
|
5906
5906
|
latest_label_sequence: number;
|
|
5907
|
+
/**
|
|
5908
|
+
* @description Label objects fetched for this request. Zero on a materialized-cache hit;
|
|
5909
|
+
* a rebuild reports the bounded source objects it read.
|
|
5910
|
+
*/
|
|
5907
5911
|
objects_scanned: number;
|
|
5908
5912
|
promoted_models: components["schemas"]["SearchFeedbackPromotedModel"][];
|
|
5909
5913
|
raw_events: number;
|
|
@@ -6757,7 +6761,28 @@ export interface components {
|
|
|
6757
6761
|
*/
|
|
6758
6762
|
hit_rate_at_k: number;
|
|
6759
6763
|
/** Format: double */
|
|
6764
|
+
latency_p50_ms?: number;
|
|
6765
|
+
/** Format: double */
|
|
6766
|
+
latency_p95_ms?: number;
|
|
6767
|
+
/** Format: double */
|
|
6768
|
+
latency_p99_ms?: number;
|
|
6769
|
+
/** Format: double */
|
|
6760
6770
|
mean_latency_ms: number;
|
|
6771
|
+
/**
|
|
6772
|
+
* Format: float
|
|
6773
|
+
* @description Mean reciprocal rank of the first expected target in top-k.
|
|
6774
|
+
*/
|
|
6775
|
+
mrr_at_k?: number;
|
|
6776
|
+
/**
|
|
6777
|
+
* Format: float
|
|
6778
|
+
* @description Mean binary-relevance nDCG over top-k.
|
|
6779
|
+
*/
|
|
6780
|
+
ndcg_at_k?: number;
|
|
6781
|
+
/**
|
|
6782
|
+
* Format: float
|
|
6783
|
+
* @description Mean fraction of each query's expected targets recovered in top-k.
|
|
6784
|
+
*/
|
|
6785
|
+
recall_at_k?: number;
|
|
6761
6786
|
};
|
|
6762
6787
|
/**
|
|
6763
6788
|
* @description `POST /v1/models/shadow-eval` — champion vs challenger retrieval over the
|
|
@@ -7496,6 +7521,32 @@ export interface components {
|
|
|
7496
7521
|
/** @description Human-readable one-liner for the console status surface. */
|
|
7497
7522
|
reason: string;
|
|
7498
7523
|
};
|
|
7524
|
+
/** @description Bounded in-flight work counters for a durable trainer job. */
|
|
7525
|
+
TrainModelJobProgress: {
|
|
7526
|
+
completed_candidates: number;
|
|
7527
|
+
/** @description Completed expensive probe replays, not merely distinct input probes. */
|
|
7528
|
+
completed_probes: number;
|
|
7529
|
+
/**
|
|
7530
|
+
* Format: int64
|
|
7531
|
+
* @description Linear estimate from work completed so far. Absent before the first
|
|
7532
|
+
* measured probe or for trainers without fine-grained progress.
|
|
7533
|
+
*/
|
|
7534
|
+
estimated_duration_ms?: number | null;
|
|
7535
|
+
/**
|
|
7536
|
+
* Format: int64
|
|
7537
|
+
* @description Worker heartbeat attached to this progress snapshot.
|
|
7538
|
+
*/
|
|
7539
|
+
heartbeat_micros: number;
|
|
7540
|
+
/**
|
|
7541
|
+
* Format: float
|
|
7542
|
+
* @description Monotonic completion percentage in `[0, 100]`.
|
|
7543
|
+
*/
|
|
7544
|
+
percentage: number;
|
|
7545
|
+
/** @description `preparing` | `candidate_search` | `held_out_gate` | kind-specific stage. */
|
|
7546
|
+
phase: string;
|
|
7547
|
+
total_candidates: number;
|
|
7548
|
+
total_probes: number;
|
|
7549
|
+
};
|
|
7499
7550
|
/**
|
|
7500
7551
|
* @description Durable background trainer status. The terminal `result` carries the full
|
|
7501
7552
|
* snapshot lineage, held-out gate evidence, and recorded run number.
|
|
@@ -7508,6 +7559,7 @@ export interface components {
|
|
|
7508
7559
|
graph: components["schemas"]["GraphKey"];
|
|
7509
7560
|
job_id: string;
|
|
7510
7561
|
kind: string;
|
|
7562
|
+
progress?: null | components["schemas"]["TrainModelJobProgress"];
|
|
7511
7563
|
result?: null | components["schemas"]["TrainModelResponse"];
|
|
7512
7564
|
stage?: string | null;
|
|
7513
7565
|
/** @description `pending` | `running` | `succeeded` | `failed`. */
|