@littlebigbrain/client 0.7.0 → 0.8.1
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 +11 -5
- package/dist/client.d.ts +58 -186
- package/dist/client.js +113 -253
- package/dist/index.d.ts +1 -1
- package/dist/namespaces.d.ts +24 -89
- package/dist/namespaces.js +69 -196
- package/dist/schema.d.ts +1000 -5675
- package/dist/types.d.ts +28 -17
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { parseSparqlResults } from "./types.js";
|
|
2
2
|
import { bodyMarksTerminal, errorCodeFromBody, fullJitterBackoffMs, parseLbbError, parseResponseJson, retryAllowed, retryableStatus, retryDelayMs, sleep, } from "./transport.js";
|
|
3
|
-
import { ContextNamespace, EntityNamespace, GraphNamespace,
|
|
3
|
+
import { ContextNamespace, EntityNamespace, GraphNamespace, OntologyNamespace, QueryNamespace, SchemaNamespace, SearchNamespace, } from "./namespaces.js";
|
|
4
4
|
export { parseSparqlResults } from "./types.js";
|
|
5
5
|
export { LbbError } from "./transport.js";
|
|
6
|
-
export { ContextNamespace, EntityNamespace, FactsNamespace, GraphNamespace,
|
|
6
|
+
export { ContextNamespace, EntityNamespace, FactsNamespace, GraphNamespace, OntologyNamespace, QueryNamespace, SchemaNamespace, SearchNamespace, } from "./namespaces.js";
|
|
7
7
|
/**
|
|
8
8
|
* A typed HTTP client for a little big brain graph server. One instance is scoped to a
|
|
9
9
|
* single graph/branch; construct another for a different scope. All methods
|
|
@@ -24,9 +24,10 @@ export class LbbClient {
|
|
|
24
24
|
onRequest;
|
|
25
25
|
onResponse;
|
|
26
26
|
onRetry;
|
|
27
|
+
/** A5 default read consistency applied when a read omits its own value. */
|
|
28
|
+
defaultConsistency;
|
|
27
29
|
context;
|
|
28
30
|
search;
|
|
29
|
-
indexes;
|
|
30
31
|
entities;
|
|
31
32
|
schema;
|
|
32
33
|
ontology;
|
|
@@ -41,7 +42,7 @@ export class LbbClient {
|
|
|
41
42
|
this.graphName = options.graph;
|
|
42
43
|
this.branchName = options.branch;
|
|
43
44
|
this.stack = options.stack;
|
|
44
|
-
this.apiVersion = options.apiVersion ?? "2026-
|
|
45
|
+
this.apiVersion = options.apiVersion ?? "2026-07-23";
|
|
45
46
|
this.maxRetries = options.maxRetries ?? 6;
|
|
46
47
|
this.retryDelayMs = options.retryDelayMs ?? 100;
|
|
47
48
|
this.retryBudgetMs = options.retryBudgetMs ?? 60_000;
|
|
@@ -49,6 +50,7 @@ export class LbbClient {
|
|
|
49
50
|
this.onRequest = options.onRequest;
|
|
50
51
|
this.onResponse = options.onResponse;
|
|
51
52
|
this.onRetry = options.onRetry;
|
|
53
|
+
this.defaultConsistency = options.defaultConsistency;
|
|
52
54
|
if (!Number.isInteger(this.maxRetries) || this.maxRetries < 0) {
|
|
53
55
|
throw new RangeError("maxRetries must be a non-negative integer");
|
|
54
56
|
}
|
|
@@ -69,7 +71,6 @@ export class LbbClient {
|
|
|
69
71
|
this.fetchImpl = chosen;
|
|
70
72
|
this.context = new ContextNamespace(this);
|
|
71
73
|
this.search = new SearchNamespace(this);
|
|
72
|
-
this.indexes = new IndexNamespace(this);
|
|
73
74
|
this.entities = new EntityNamespace(this);
|
|
74
75
|
this.schema = new SchemaNamespace(this);
|
|
75
76
|
this.ontology = new OntologyNamespace(this);
|
|
@@ -103,8 +104,38 @@ export class LbbClient {
|
|
|
103
104
|
onRequest: this.onRequest,
|
|
104
105
|
onResponse: this.onResponse,
|
|
105
106
|
onRetry: this.onRetry,
|
|
107
|
+
defaultConsistency: this.defaultConsistency,
|
|
106
108
|
});
|
|
107
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* A5: fold read-consistency options into a request body's own `consistency` /
|
|
112
|
+
* `min_indexed_seq` fields (the shape used by full-text, embedding, and
|
|
113
|
+
* structured-SPARQL bodies). A per-call value wins over the client
|
|
114
|
+
* `defaultConsistency`; an explicit body field wins over both.
|
|
115
|
+
*/
|
|
116
|
+
resolveConsistency(opts) {
|
|
117
|
+
return opts?.consistency ?? this.defaultConsistency;
|
|
118
|
+
}
|
|
119
|
+
mergeReadConsistency(body, opts) {
|
|
120
|
+
const consistency = this.resolveConsistency(opts);
|
|
121
|
+
const merged = { ...body };
|
|
122
|
+
if (consistency !== undefined && merged.consistency === undefined) {
|
|
123
|
+
merged.consistency = consistency;
|
|
124
|
+
}
|
|
125
|
+
if (opts?.minIndexedSeq !== undefined &&
|
|
126
|
+
merged.min_indexed_seq === undefined) {
|
|
127
|
+
merged.min_indexed_seq = opts.minIndexedSeq;
|
|
128
|
+
}
|
|
129
|
+
return merged;
|
|
130
|
+
}
|
|
131
|
+
/** A5: read-consistency options rendered as URL query params, for the routes
|
|
132
|
+
* that carry consistency on the URL (SPARQL-text, graph summary). */
|
|
133
|
+
readConsistencyQuery(opts) {
|
|
134
|
+
return {
|
|
135
|
+
consistency: this.resolveConsistency(opts),
|
|
136
|
+
min_indexed_seq: opts?.minIndexedSeq,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
108
139
|
buildUrl(path, query) {
|
|
109
140
|
const params = [];
|
|
110
141
|
const push = (key, value) => params.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
|
|
@@ -292,11 +323,14 @@ export class LbbClient {
|
|
|
292
323
|
}
|
|
293
324
|
// --- writes ---
|
|
294
325
|
/** Commit triplets and optional entity embeddings. Prefer `client.graph("main").facts.create(...)`. */
|
|
295
|
-
commit(body, opts = {}) {
|
|
296
|
-
|
|
326
|
+
async commit(body, opts = {}) {
|
|
327
|
+
const response = await this.request("POST", "/v1/graph/commit", {
|
|
297
328
|
body,
|
|
298
329
|
idempotencyKey: opts.idempotencyKey ?? this.idempotencyKey("facts.create"),
|
|
299
330
|
});
|
|
331
|
+
// A5: surface the committed sequence as `commitSeq` so the write→floor→read
|
|
332
|
+
// loop reads naturally: `const { commitSeq } = await client.commit(…)`.
|
|
333
|
+
return { ...response, commitSeq: response.commit_seq };
|
|
300
334
|
}
|
|
301
335
|
/**
|
|
302
336
|
* Validate-only preflight: run the same ontology/schema validation a real
|
|
@@ -318,28 +352,28 @@ export class LbbClient {
|
|
|
318
352
|
* streamed request without a single oversized commit. Pass `lines` as an array
|
|
319
353
|
* (serialized to NDJSON here) or a pre-built NDJSON string.
|
|
320
354
|
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
* the throttle): import the whole dataset, index once. The response's `index`
|
|
326
|
-
* object reports whether the build ran or was skipped.
|
|
355
|
+
* A successful import durably enqueues one complete published-generation
|
|
356
|
+
* build after the final batch. It does not build index families or wait for
|
|
357
|
+
* visibility; the response's `published_generation` object carries the
|
|
358
|
+
* durable job and due sequence to observe.
|
|
327
359
|
*/
|
|
328
|
-
import(lines, opts = {}) {
|
|
360
|
+
async import(lines, opts = {}) {
|
|
329
361
|
const ndjson = typeof lines === "string"
|
|
330
362
|
? lines
|
|
331
363
|
: lines.map((line) => JSON.stringify(line)).join("\n");
|
|
332
|
-
|
|
364
|
+
const response = await this.request("POST", "/v1/graph/import", {
|
|
333
365
|
rawBody: ndjson,
|
|
334
366
|
contentType: "application/x-ndjson",
|
|
335
367
|
query: {
|
|
336
368
|
batch: opts.batch,
|
|
337
369
|
strict: opts.strict,
|
|
338
370
|
observed_at: opts.observedAt,
|
|
339
|
-
index: opts.index,
|
|
340
371
|
},
|
|
341
372
|
idempotencyKey: opts.idempotencyKey ?? this.idempotencyKey("import"),
|
|
342
373
|
});
|
|
374
|
+
// A5: surface the last committed sequence (null for an empty import) so the
|
|
375
|
+
// write→floor→read loop reads naturally after a bulk load.
|
|
376
|
+
return { ...response, commitSeq: response.committed_commit_seq ?? null };
|
|
343
377
|
}
|
|
344
378
|
/**
|
|
345
379
|
* Bulk-ingest N-Triples, Turtle, N-Quads, or TriG without client-side conversion. Resource-object
|
|
@@ -371,19 +405,6 @@ export class LbbClient {
|
|
|
371
405
|
idempotencyKey: opts.idempotencyKey ?? this.idempotencyKey("import-rdf"),
|
|
372
406
|
});
|
|
373
407
|
}
|
|
374
|
-
/** Export the snapshot-visible RDF projection as Turtle, N-Triples, TriG, or N-Quads. */
|
|
375
|
-
exportRdf(opts = {}) {
|
|
376
|
-
return this.request("GET", "/v1/graph/export/rdf", {
|
|
377
|
-
query: {
|
|
378
|
-
format: opts.format === "ntriples" ? "nt" : opts.format,
|
|
379
|
-
max_triples: opts.maxTriples,
|
|
380
|
-
as_of_valid_time: opts.asOfValidTime,
|
|
381
|
-
as_of_commit_seq: opts.asOfCommitSeq,
|
|
382
|
-
entailment: opts.entailment,
|
|
383
|
-
reason: opts.reason,
|
|
384
|
-
},
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
408
|
/**
|
|
388
409
|
* Retract specific edges and/or every edge touching given entities. Appends
|
|
389
410
|
* superseding retract events rather than deleting — history stays visible in an
|
|
@@ -601,23 +622,19 @@ export class LbbClient {
|
|
|
601
622
|
query: { kind: opts.kind, run: opts.run },
|
|
602
623
|
});
|
|
603
624
|
}
|
|
604
|
-
/**
|
|
605
|
-
* Champion vs challenger retrieval over one pinned snapshot. Returns
|
|
606
|
-
* promotion evidence (hit-rate@k, latency, overlap); never promotes.
|
|
607
|
-
*/
|
|
608
|
-
shadowEval(body) {
|
|
609
|
-
return this.request("POST", "/v1/models/shadow-eval", { body });
|
|
610
|
-
}
|
|
611
|
-
/**
|
|
612
|
-
* Execution-verified QA probes generated from the graph's current edges —
|
|
613
|
-
* labels are the executed projections, so they are verified by construction.
|
|
614
|
-
* Feeds `shadowEval` directly.
|
|
615
|
-
*/
|
|
625
|
+
/** Execution-verified QA probes generated from the graph's current edges. */
|
|
616
626
|
syntheticEval(opts = {}) {
|
|
617
627
|
return this.request("GET", "/v1/models/synthetic-eval", {
|
|
618
628
|
query: { limit: opts.limit },
|
|
619
629
|
});
|
|
620
630
|
}
|
|
631
|
+
/**
|
|
632
|
+
* Compare champion and challenger retrieval over one pinned published
|
|
633
|
+
* snapshot. The endpoint returns promotion evidence but never promotes.
|
|
634
|
+
*/
|
|
635
|
+
shadowEval(body) {
|
|
636
|
+
return this.request("POST", "/v1/models/shadow-eval", { body });
|
|
637
|
+
}
|
|
621
638
|
/** The doubling retrain policy: is a retrain due for this model kind? */
|
|
622
639
|
modelCadence(opts) {
|
|
623
640
|
return this.request("GET", "/v1/models/cadence", {
|
|
@@ -643,18 +660,6 @@ export class LbbClient {
|
|
|
643
660
|
setTrainingConfig(body) {
|
|
644
661
|
return this.request("POST", "/v1/models/training-config", { body });
|
|
645
662
|
}
|
|
646
|
-
/**
|
|
647
|
-
* Verdict on an ask (`accepted` | `rejected` | `corrected` + the right
|
|
648
|
-
* plan), joined to the ask's trace by `ask_id` — the planner fine-tune's
|
|
649
|
-
* explicit feedback capture. `accepted: false` in the response means
|
|
650
|
-
* signal capture is off on this deployment (the contract is identical).
|
|
651
|
-
*/
|
|
652
|
-
askFeedback(body, opts = {}) {
|
|
653
|
-
return this.request("POST", "/v1/ask/feedback", {
|
|
654
|
-
body,
|
|
655
|
-
idempotencyKey: opts.idempotencyKey ?? this.idempotencyKey("ask-feedback"),
|
|
656
|
-
});
|
|
657
|
-
}
|
|
658
663
|
ingestSignals(body, opts = {}) {
|
|
659
664
|
return this.request("POST", "/v1/signals", {
|
|
660
665
|
body,
|
|
@@ -679,39 +684,25 @@ export class LbbClient {
|
|
|
679
684
|
],
|
|
680
685
|
}, opts);
|
|
681
686
|
}
|
|
682
|
-
/**
|
|
683
|
-
* The planner fine-tune's training feed: accepted/corrected feedback
|
|
684
|
-
* joined to its traces (signals ≤ the split pin), topped up with
|
|
685
|
-
* execution-verified synthetic plans.
|
|
686
|
-
*/
|
|
687
|
+
/** Planner training examples at or before an optional signal split. */
|
|
687
688
|
plannerDataset(opts = {}) {
|
|
688
689
|
return this.request("GET", "/v1/models/planner-dataset", {
|
|
689
690
|
query: { limit: opts.limit, split_seq: opts.splitSeq },
|
|
690
691
|
});
|
|
691
692
|
}
|
|
692
|
-
/**
|
|
693
|
-
* The DPO pass's training feed: preference pairs from corrected verdicts,
|
|
694
|
-
* paired rejections, and synthetic corrupted-slot pairs.
|
|
695
|
-
*/
|
|
693
|
+
/** Planner preference pairs at or before an optional signal split. */
|
|
696
694
|
plannerPreferenceDataset(opts = {}) {
|
|
697
695
|
return this.request("GET", "/v1/models/planner-preference-dataset", {
|
|
698
696
|
query: { limit: opts.limit, split_seq: opts.splitSeq },
|
|
699
697
|
});
|
|
700
698
|
}
|
|
701
|
-
/**
|
|
702
|
-
* The suggest-ranker trainer's probe feed: `suggestion_adopted` signals
|
|
703
|
-
* (typed prefix + adopted text) ≤ the split pin, topped up with
|
|
704
|
-
* execution-verified synthetic vocabulary pairs.
|
|
705
|
-
*/
|
|
699
|
+
/** Suggest-ranker examples at or before an optional signal split. */
|
|
706
700
|
suggestDataset(opts = {}) {
|
|
707
701
|
return this.request("GET", "/v1/models/suggest-dataset", {
|
|
708
702
|
query: { limit: opts.limit, split_seq: opts.splitSeq },
|
|
709
703
|
});
|
|
710
704
|
}
|
|
711
|
-
/**
|
|
712
|
-
* The extractor fine-tune's training feed: EPISODE transcripts joined to
|
|
713
|
-
* the facts the observe pipeline committed from them.
|
|
714
|
-
*/
|
|
705
|
+
/** Extractor examples at or before an optional signal split. */
|
|
715
706
|
extractorDataset(opts = {}) {
|
|
716
707
|
return this.request("GET", "/v1/models/extractor-dataset", {
|
|
717
708
|
query: { limit: opts.limit, split_seq: opts.splitSeq },
|
|
@@ -729,8 +720,7 @@ export class LbbClient {
|
|
|
729
720
|
}
|
|
730
721
|
/**
|
|
731
722
|
* Promote a finished `planner_lora` training run: gated on held-out slot
|
|
732
|
-
* exactness
|
|
733
|
-
* then serves.
|
|
723
|
+
* exactness and recorded as a `kind=planner` training run.
|
|
734
724
|
*/
|
|
735
725
|
promotePlanner(opts) {
|
|
736
726
|
return this.request("POST", "/v1/models/promote-planner", {
|
|
@@ -739,8 +729,15 @@ export class LbbClient {
|
|
|
739
729
|
}
|
|
740
730
|
// --- search ---
|
|
741
731
|
/** Full semantic hybrid search from a request body (`POST /v1/graph/search`). */
|
|
742
|
-
graphSearch(body) {
|
|
743
|
-
|
|
732
|
+
graphSearch(body, opts) {
|
|
733
|
+
// Consistency for hybrid graph search lives on the nested `search` options.
|
|
734
|
+
const consistency = this.resolveConsistency(opts);
|
|
735
|
+
const search = consistency !== undefined || opts?.minIndexedSeq !== undefined
|
|
736
|
+
? this.mergeReadConsistency(body.search ?? {}, opts)
|
|
737
|
+
: body.search;
|
|
738
|
+
return this.request("POST", "/v1/graph/search", {
|
|
739
|
+
body: { ...body, search },
|
|
740
|
+
});
|
|
744
741
|
}
|
|
745
742
|
/** Reciprocal-rank-fusion across sub-queries. */
|
|
746
743
|
multiSearch(body) {
|
|
@@ -754,37 +751,18 @@ export class LbbClient {
|
|
|
754
751
|
suggest(body) {
|
|
755
752
|
return this.request("POST", "/v1/search/suggest", { body });
|
|
756
753
|
}
|
|
757
|
-
/**
|
|
758
|
-
* Snap free text to the nearest real vocabulary item. Embedding cosine
|
|
759
|
-
* on a managed graph, else lexical; never fabricates a term.
|
|
760
|
-
*/
|
|
754
|
+
/** Snap free text to the nearest term in the pinned published vocabulary. */
|
|
761
755
|
resolveTerm(body) {
|
|
762
756
|
return this.request("POST", "/v1/search/resolve-term", { body });
|
|
763
757
|
}
|
|
764
|
-
/**
|
|
765
|
-
* Ground a natural-language question to the graph's real vocabulary, retrieve
|
|
766
|
-
* against the pinned snapshot, and answer with citations (`/v1/ask`).
|
|
767
|
-
*/
|
|
768
|
-
ask(body) {
|
|
769
|
-
return this.request("POST", "/v1/ask", { body });
|
|
770
|
-
}
|
|
771
|
-
/**
|
|
772
|
-
* Name the relation between two entities (`/v1/decode`): the DB narrows the
|
|
773
|
-
* candidates to the type pair's admissible relations, answers alone
|
|
774
|
-
* when the pair forces a single relation, and otherwise decodes it with the
|
|
775
|
-
* graph-native fine-tuned model — the "DB narrows, cheap model decodes" call.
|
|
776
|
-
*/
|
|
758
|
+
/** Decode a relation from the graph's admissible published vocabulary. */
|
|
777
759
|
decode(body) {
|
|
778
760
|
return this.request("POST", "/v1/decode", { body });
|
|
779
761
|
}
|
|
780
|
-
/**
|
|
781
|
-
* Report which completion mechanisms will carry on this graph:
|
|
782
|
-
* signature sparsity, name semantics, sampled narrowing recall, and a
|
|
783
|
-
* narrow / narrow+finetune / lexical-first recommendation.
|
|
784
|
-
*/
|
|
762
|
+
/** Report completion strategy fitness for the pinned published graph. */
|
|
785
763
|
groundability(opts = {}) {
|
|
786
764
|
return this.request("GET", "/v1/graph/groundability", {
|
|
787
|
-
query: opts.sample
|
|
765
|
+
query: opts.sample == null ? undefined : { sample: opts.sample },
|
|
788
766
|
});
|
|
789
767
|
}
|
|
790
768
|
/**
|
|
@@ -805,12 +783,16 @@ export class LbbClient {
|
|
|
805
783
|
return this.request("GET", "/v1/search/feedback/export");
|
|
806
784
|
}
|
|
807
785
|
/** BM25 search. */
|
|
808
|
-
fullTextSearch(body) {
|
|
809
|
-
return this.request("POST", "/v1/search/full-text", {
|
|
786
|
+
fullTextSearch(body, opts) {
|
|
787
|
+
return this.request("POST", "/v1/search/full-text", {
|
|
788
|
+
body: this.mergeReadConsistency(body, opts),
|
|
789
|
+
});
|
|
810
790
|
}
|
|
811
791
|
/** ANN/vector search. */
|
|
812
|
-
embeddingSearch(body) {
|
|
813
|
-
return this.request("POST", "/v1/search/embedding", {
|
|
792
|
+
embeddingSearch(body, opts) {
|
|
793
|
+
return this.request("POST", "/v1/search/embedding", {
|
|
794
|
+
body: this.mergeReadConsistency(body, opts),
|
|
795
|
+
});
|
|
814
796
|
}
|
|
815
797
|
// --- traversal ---
|
|
816
798
|
/** Bounded k-hop graph traversal. */
|
|
@@ -830,7 +812,6 @@ export class LbbClient {
|
|
|
830
812
|
name: opts.name,
|
|
831
813
|
relations: opts.relations?.join(","),
|
|
832
814
|
as_of: opts.asOf,
|
|
833
|
-
indexed: opts.indexed,
|
|
834
815
|
},
|
|
835
816
|
});
|
|
836
817
|
}
|
|
@@ -870,39 +851,11 @@ export class LbbClient {
|
|
|
870
851
|
},
|
|
871
852
|
});
|
|
872
853
|
}
|
|
873
|
-
/**
|
|
874
|
-
* Paged edge listing. Scope to one node with `id` (or `type`+`name`) and a
|
|
875
|
-
* `direction` (`out`/`in`/`both`) to walk **every** edge of a high-degree node
|
|
876
|
-
* — `entityDetail` returns the full set but is awkward to page; this carries
|
|
877
|
-
* `offset`/`limit` and reports `total_count`. Optional `relation`/`q` filters
|
|
878
|
-
* and an `asOf`/`asOfCommitSeq` snapshot pin. Each row carries `valid_time`, so
|
|
879
|
-
* the page is enough to reconstruct a per-edge timeline.
|
|
880
|
-
*/
|
|
881
|
-
graphEdges(opts = {}) {
|
|
882
|
-
return this.request("GET", "/v1/graph/edges", {
|
|
883
|
-
query: {
|
|
884
|
-
id: opts.id,
|
|
885
|
-
type: opts.type,
|
|
886
|
-
name: opts.name,
|
|
887
|
-
direction: opts.direction,
|
|
888
|
-
relation: opts.relation,
|
|
889
|
-
q: opts.q,
|
|
890
|
-
limit: opts.limit,
|
|
891
|
-
cursor: opts.cursor,
|
|
892
|
-
offset: opts.offset,
|
|
893
|
-
as_of: opts.asOf,
|
|
894
|
-
as_of_commit_seq: opts.asOfCommitSeq,
|
|
895
|
-
},
|
|
896
|
-
});
|
|
897
|
-
}
|
|
898
854
|
/**
|
|
899
855
|
* Page through every row of a list endpoint, following `next_cursor` until
|
|
900
856
|
* exhausted. Pass a fetcher that takes a cursor and returns a
|
|
901
857
|
* {@link ListResponse}:
|
|
902
|
-
*
|
|
903
|
-
* for await (const e of client.listAll((cursor) =>
|
|
904
|
-
* client.entities.list({ cursor, fields: "title" }))) { … }
|
|
905
|
-
* ```
|
|
858
|
+
* The caller supplies a bounded collection endpoint and its cursor.
|
|
906
859
|
*/
|
|
907
860
|
async *listAll(fetchPage) {
|
|
908
861
|
let cursor;
|
|
@@ -932,10 +885,6 @@ export class LbbClient {
|
|
|
932
885
|
why(body) {
|
|
933
886
|
return this.request("POST", "/v1/query/why", { body });
|
|
934
887
|
}
|
|
935
|
-
/** SHACL-style shape/pattern query. */
|
|
936
|
-
shacl(body) {
|
|
937
|
-
return this.request("POST", "/v1/query/shacl", { body });
|
|
938
|
-
}
|
|
939
888
|
/**
|
|
940
889
|
* SPARQL-subset SELECT/ASK/aggregate query (FILTER, HAVING, ORDER BY, ASK,
|
|
941
890
|
* COUNT/SUM/AVG/MIN/MAX). GROUP BY is not limited to entity identity:
|
|
@@ -946,12 +895,17 @@ export class LbbClient {
|
|
|
946
895
|
* keys come back per group in `groups[].value_keys[<as>]`, entity keys in
|
|
947
896
|
* `groups[].keys`.
|
|
948
897
|
*/
|
|
949
|
-
sparql(body) {
|
|
950
|
-
return this.request("POST", "/v1/query/sparql", {
|
|
898
|
+
sparql(body, opts) {
|
|
899
|
+
return this.request("POST", "/v1/query/sparql", {
|
|
900
|
+
body: this.mergeReadConsistency(body, opts),
|
|
901
|
+
});
|
|
951
902
|
}
|
|
952
|
-
/** SPARQL 1.1 query from text (SELECT/ASK) over the live graph; `results` is SPARQL 1.1 Query Results JSON. */
|
|
953
|
-
sparqlText(body) {
|
|
954
|
-
return this.request("POST", "/v1/query/sparql-text", {
|
|
903
|
+
/** SPARQL 1.1 query from text (SELECT/ASK) over the live graph; `results` is SPARQL 1.1 Query Results JSON. The text dialect carries `consistency`/`min_indexed_seq` on the URL. */
|
|
904
|
+
sparqlText(body, opts) {
|
|
905
|
+
return this.request("POST", "/v1/query/sparql-text", {
|
|
906
|
+
body,
|
|
907
|
+
query: this.readConsistencyQuery(opts),
|
|
908
|
+
});
|
|
955
909
|
}
|
|
956
910
|
/**
|
|
957
911
|
* Run a SPARQL 1.1 text query and return parsed results — the ergonomic
|
|
@@ -960,8 +914,8 @@ export class LbbClient {
|
|
|
960
914
|
* `rows` is the bindings flattened to `{ variable: lexicalValue }`, `boolean`
|
|
961
915
|
* is the ASK answer (or `null` for a SELECT).
|
|
962
916
|
*/
|
|
963
|
-
async sparqlRows(body) {
|
|
964
|
-
return parseSparqlResults(await this.sparqlText(body));
|
|
917
|
+
async sparqlRows(body, opts) {
|
|
918
|
+
return parseSparqlResults(await this.sparqlText(body, opts));
|
|
965
919
|
}
|
|
966
920
|
/**
|
|
967
921
|
* Basic-graph-pattern query with group-graph-pattern combinators
|
|
@@ -973,36 +927,6 @@ export class LbbClient {
|
|
|
973
927
|
analytics(body) {
|
|
974
928
|
return this.request("POST", "/v1/query/analytics", { body });
|
|
975
929
|
}
|
|
976
|
-
/**
|
|
977
|
-
* Run inference rules (SHACL-AF `sh:TripleRule` shape) to a bounded fixpoint
|
|
978
|
-
* and return the derived edges as a **preview** — derived facts are never
|
|
979
|
-
* written to the asserted graph. Each rule is a BGP `body`/`where` plus a
|
|
980
|
-
* `head` triple template instantiated per binding.
|
|
981
|
-
*/
|
|
982
|
-
infer(body) {
|
|
983
|
-
return this.request("POST", "/v1/inference/run", { body });
|
|
984
|
-
}
|
|
985
|
-
/**
|
|
986
|
-
* Define (replace) the versioned rule set stored on the scoped graph branch.
|
|
987
|
-
* The stored set is what SHACL `include_derived` and `infer` use when a
|
|
988
|
-
* request carries no inline rules. Returns the new `rules_version`.
|
|
989
|
-
*/
|
|
990
|
-
defineRules(body) {
|
|
991
|
-
return this.request("POST", "/v1/inference/rules", { body });
|
|
992
|
-
}
|
|
993
|
-
/** The rule set stored on the scoped graph branch (version + rules). */
|
|
994
|
-
graphRules() {
|
|
995
|
-
return this.request("GET", "/v1/inference/rules");
|
|
996
|
-
}
|
|
997
|
-
/**
|
|
998
|
-
* Derive edges from calibrated retrieval matches (preview): each
|
|
999
|
-
* candidate scored `P >= threshold` becomes a derived edge `(anchor, relation,
|
|
1000
|
-
* matched)` with a typed `Retrieval` provenance leaf. Pass either explicit
|
|
1001
|
-
* `candidates` or a `query` the server runs as BM25 entity retrieval.
|
|
1002
|
-
*/
|
|
1003
|
-
retrievalPremises(body) {
|
|
1004
|
-
return this.request("POST", "/v1/inference/retrieval-premises", { body });
|
|
1005
|
-
}
|
|
1006
930
|
// --- ontology ---
|
|
1007
931
|
/**
|
|
1008
932
|
* The active ontology (entity types and relations) for the scoped graph.
|
|
@@ -1019,12 +943,13 @@ export class LbbClient {
|
|
|
1019
943
|
* Audit the current snapshot against the ontology's *implied* constraints —
|
|
1020
944
|
* capped `cardinality` derived as `sh:maxCount` — returning a SHACL-shaped
|
|
1021
945
|
* report. Whole-snapshot and never blocks a write. Unlike
|
|
1022
|
-
*
|
|
1023
|
-
*
|
|
1024
|
-
* {@link ontologyView} for which decorations are enforced.
|
|
946
|
+
* The report is referenced by the pinned published read root and carries its
|
|
947
|
+
* own validation watermark and ontology/shapes provenance.
|
|
1025
948
|
*/
|
|
1026
|
-
ontologyConformance() {
|
|
1027
|
-
return this.request("GET", "/v1/ontology/conformance"
|
|
949
|
+
ontologyConformance(opts) {
|
|
950
|
+
return this.request("GET", "/v1/ontology/conformance", {
|
|
951
|
+
query: { consistency: this.resolveConsistency(opts) },
|
|
952
|
+
});
|
|
1028
953
|
}
|
|
1029
954
|
/** Discover ontology concepts, terms, and relations. */
|
|
1030
955
|
ontologySearch(body) {
|
|
@@ -1051,75 +976,6 @@ export class LbbClient {
|
|
|
1051
976
|
induceOntology(body) {
|
|
1052
977
|
return this.request("POST", "/v1/ontology/induce", { body, retry: true });
|
|
1053
978
|
}
|
|
1054
|
-
// --- index lifecycle ---
|
|
1055
|
-
/**
|
|
1056
|
-
* Build default ANN + BM25 indexes. With `{ background: true }` the build
|
|
1057
|
-
* runs detached on the server and the call returns immediately — use it for
|
|
1058
|
-
* large corpora whose synchronous build would exceed a fronting gateway's
|
|
1059
|
-
* timeout (a 504), then poll `metadata()` for completion.
|
|
1060
|
-
*/
|
|
1061
|
-
indexBuild(opts = {}) {
|
|
1062
|
-
return this.request("POST", "/v1/index/build", {
|
|
1063
|
-
query: { background: opts.background || undefined },
|
|
1064
|
-
});
|
|
1065
|
-
}
|
|
1066
|
-
/**
|
|
1067
|
-
* Build BM25, ANN/vector, and adjacency index families. With
|
|
1068
|
-
* `{ background: true }` the build runs detached on the server and the call
|
|
1069
|
-
* returns immediately — use it for large corpora whose synchronous build would
|
|
1070
|
-
* exceed a fronting gateway's timeout, then poll `metadata()` for completion.
|
|
1071
|
-
*/
|
|
1072
|
-
indexRun(opts = {}) {
|
|
1073
|
-
return this.request("POST", "/v1/index/run", {
|
|
1074
|
-
query: { background: opts.background || undefined },
|
|
1075
|
-
});
|
|
1076
|
-
}
|
|
1077
|
-
/** Submit a durable full-index build. Requires a reconnect-safe idempotency key. */
|
|
1078
|
-
indexSubmit(body = {}, opts) {
|
|
1079
|
-
return this.request("POST", "/v1/index/jobs", {
|
|
1080
|
-
body,
|
|
1081
|
-
idempotencyKey: opts.idempotencyKey,
|
|
1082
|
-
});
|
|
1083
|
-
}
|
|
1084
|
-
/** Poll a durable full-index build. */
|
|
1085
|
-
indexJob(jobId) {
|
|
1086
|
-
return this.request("GET", "/v1/index/jobs", { query: { job_id: jobId } });
|
|
1087
|
-
}
|
|
1088
|
-
/** Cancel a durable full-index build. Repeated cancellation returns its current terminal status. */
|
|
1089
|
-
cancelIndexJob(jobId) {
|
|
1090
|
-
return this.request("DELETE", "/v1/index/jobs", {
|
|
1091
|
-
query: { job_id: jobId },
|
|
1092
|
-
});
|
|
1093
|
-
}
|
|
1094
|
-
/** Append a BM25 delta segment for the unindexed WAL tail. */
|
|
1095
|
-
indexDelta() {
|
|
1096
|
-
return this.request("POST", "/v1/index/delta");
|
|
1097
|
-
}
|
|
1098
|
-
/** Preview or delete superseded persisted index runs. */
|
|
1099
|
-
indexGc(opts = {}) {
|
|
1100
|
-
return this.request("POST", "/v1/index/gc", {
|
|
1101
|
-
query: { keep_runs: opts.keepRuns, dry_run: opts.dryRun },
|
|
1102
|
-
});
|
|
1103
|
-
}
|
|
1104
|
-
/** Submit durable, cancellable index garbage collection. */
|
|
1105
|
-
indexGcSubmit(body = {}, opts) {
|
|
1106
|
-
return this.request("POST", "/v1/index/gc-jobs", {
|
|
1107
|
-
body,
|
|
1108
|
-
idempotencyKey: opts.idempotencyKey,
|
|
1109
|
-
});
|
|
1110
|
-
}
|
|
1111
|
-
/** Poll exact planning/deletion progress for durable index garbage collection. */
|
|
1112
|
-
indexGcJob(jobId) {
|
|
1113
|
-
return this.request("GET", "/v1/index/gc-jobs", {
|
|
1114
|
-
query: { job_id: jobId },
|
|
1115
|
-
});
|
|
1116
|
-
}
|
|
1117
|
-
/** Cancel durable index garbage collection. */
|
|
1118
|
-
cancelIndexGcJob(jobId) {
|
|
1119
|
-
return this.request("DELETE", "/v1/index/gc-jobs", {
|
|
1120
|
-
query: { job_id: jobId },
|
|
1121
|
-
});
|
|
1122
|
-
}
|
|
1123
979
|
/** Fold the WAL tail into snapshot segments. */
|
|
1124
980
|
compact(opts = {}) {
|
|
1125
981
|
return this.request("POST", "/v1/graph/compact", {
|
|
@@ -1134,13 +990,11 @@ export class LbbClient {
|
|
|
1134
990
|
status() {
|
|
1135
991
|
return this.request("GET", "/v1/status");
|
|
1136
992
|
}
|
|
1137
|
-
/** Graph footprint, WAL tail, and index coverage.
|
|
993
|
+
/** Graph footprint, WAL tail, and published-index coverage. */
|
|
1138
994
|
metadata(opts = {}) {
|
|
1139
995
|
return this.request("GET", "/v1/graph/metadata", {
|
|
1140
996
|
query: {
|
|
1141
|
-
include_objects: opts.includeObjects,
|
|
1142
997
|
include_indexes: opts.includeIndexes,
|
|
1143
|
-
include_temporal_coverage: opts.includeTemporalCoverage,
|
|
1144
998
|
},
|
|
1145
999
|
});
|
|
1146
1000
|
}
|
|
@@ -1175,9 +1029,15 @@ export class LbbClient {
|
|
|
1175
1029
|
await sleep(opts.pollIntervalMs ?? 250);
|
|
1176
1030
|
}
|
|
1177
1031
|
}
|
|
1178
|
-
/** Graph counts and type/relation buckets. */
|
|
1179
|
-
summary() {
|
|
1180
|
-
return this.request("GET", "/v1/graph/summary"
|
|
1032
|
+
/** Graph counts and type/relation buckets. Carries `consistency`/`min_indexed_seq` on the URL. */
|
|
1033
|
+
summary(opts) {
|
|
1034
|
+
return this.request("GET", "/v1/graph/summary", {
|
|
1035
|
+
query: this.readConsistencyQuery(opts),
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
/** Pinned published read root and its query/conformance lag against one coherent head. */
|
|
1039
|
+
readSnapshot() {
|
|
1040
|
+
return this.request("GET", "/v1/graph/read-snapshot");
|
|
1181
1041
|
}
|
|
1182
1042
|
/** List the graphs (and branches) under the scoped tenant. */
|
|
1183
1043
|
listGraphs() {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { LbbClient, LbbError, parseSparqlResults } from "./client.js";
|
|
2
|
-
export type { LbbClientOptions, CallOptions, RequestOptions,
|
|
2
|
+
export type { LbbClientOptions, CallOptions, RequestOptions, HybridSearchOptions, LbbRequestEvent, LbbResponseEvent, FetchLike, ReadConsistencyOptions, SearchConsistency, Schemas, SparqlResults, SparqlResultsJson, SparqlTerm, CommitRequest, CommitResponse, Entity, EntitySelector, GraphMetadata, GraphSummary, SchemaView, SearchRequest, SearchResponse, SearchResult, Snapshot, } from "./client.js";
|
|
3
3
|
export type { components, paths, operations } from "./schema.js";
|