@littlebigbrain/client 0.8.0 → 0.9.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 +25 -5
- package/dist/client.d.ts +55 -176
- package/dist/client.js +184 -236
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/namespaces.d.ts +15 -84
- package/dist/namespaces.js +31 -190
- package/dist/schema.d.ts +1164 -5164
- package/dist/transport.d.ts +9 -2
- package/dist/transport.js +9 -0
- package/dist/types.d.ts +6 -17
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -1,9 +1,74 @@
|
|
|
1
1
|
import { parseSparqlResults } from "./types.js";
|
|
2
2
|
import { bodyMarksTerminal, errorCodeFromBody, fullJitterBackoffMs, parseLbbError, parseResponseJson, retryAllowed, retryableStatus, retryDelayMs, sleep, } from "./transport.js";
|
|
3
|
-
import {
|
|
3
|
+
import { LbbCapabilityError } from "./transport.js";
|
|
4
|
+
import { ContextNamespace, EntityNamespace, GraphNamespace, OntologyNamespace, QueryNamespace, SchemaNamespace, SearchNamespace, } from "./namespaces.js";
|
|
4
5
|
export { parseSparqlResults } from "./types.js";
|
|
5
|
-
export { LbbError } from "./transport.js";
|
|
6
|
-
export { ContextNamespace, EntityNamespace, FactsNamespace, GraphNamespace,
|
|
6
|
+
export { LbbCapabilityError, LbbError } from "./transport.js";
|
|
7
|
+
export { ContextNamespace, EntityNamespace, FactsNamespace, GraphNamespace, OntologyNamespace, QueryNamespace, SchemaNamespace, SearchNamespace, } from "./namespaces.js";
|
|
8
|
+
function durableImportBytes(line) {
|
|
9
|
+
if (line instanceof Uint8Array)
|
|
10
|
+
return line;
|
|
11
|
+
const encoded = typeof line === "string" ? line : JSON.stringify(line);
|
|
12
|
+
return new TextEncoder().encode(encoded.endsWith("\n") ? encoded : `${encoded}\n`);
|
|
13
|
+
}
|
|
14
|
+
function durableImportIterator(source) {
|
|
15
|
+
if (typeof source === "string") {
|
|
16
|
+
return (async function* () {
|
|
17
|
+
yield source;
|
|
18
|
+
})();
|
|
19
|
+
}
|
|
20
|
+
if (Symbol.asyncIterator in Object(source)) {
|
|
21
|
+
return source[Symbol.asyncIterator]();
|
|
22
|
+
}
|
|
23
|
+
const iterator = source[Symbol.iterator]();
|
|
24
|
+
return {
|
|
25
|
+
next: async () => iterator.next(),
|
|
26
|
+
return: async () => {
|
|
27
|
+
iterator.return?.();
|
|
28
|
+
return { done: true, value: undefined };
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function durableImportBody(source) {
|
|
33
|
+
const iterator = durableImportIterator(source);
|
|
34
|
+
const Stream = globalThis.ReadableStream;
|
|
35
|
+
if (Stream) {
|
|
36
|
+
return new Stream({
|
|
37
|
+
async pull(controller) {
|
|
38
|
+
try {
|
|
39
|
+
const item = await iterator.next();
|
|
40
|
+
if (item.done) {
|
|
41
|
+
controller.close();
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
controller.enqueue(durableImportBytes(item.value));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
controller.error(error);
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
async cancel() {
|
|
52
|
+
await iterator.return?.();
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
async *[Symbol.asyncIterator]() {
|
|
58
|
+
try {
|
|
59
|
+
for (;;) {
|
|
60
|
+
const item = await iterator.next();
|
|
61
|
+
if (item.done)
|
|
62
|
+
return;
|
|
63
|
+
yield durableImportBytes(item.value);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
await iterator.return?.();
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
7
72
|
/**
|
|
8
73
|
* A typed HTTP client for a little big brain graph server. One instance is scoped to a
|
|
9
74
|
* single graph/branch; construct another for a different scope. All methods
|
|
@@ -24,11 +89,11 @@ export class LbbClient {
|
|
|
24
89
|
onRequest;
|
|
25
90
|
onResponse;
|
|
26
91
|
onRetry;
|
|
92
|
+
capabilities;
|
|
27
93
|
/** A5 default read consistency applied when a read omits its own value. */
|
|
28
94
|
defaultConsistency;
|
|
29
95
|
context;
|
|
30
96
|
search;
|
|
31
|
-
indexes;
|
|
32
97
|
entities;
|
|
33
98
|
schema;
|
|
34
99
|
ontology;
|
|
@@ -43,7 +108,7 @@ export class LbbClient {
|
|
|
43
108
|
this.graphName = options.graph;
|
|
44
109
|
this.branchName = options.branch;
|
|
45
110
|
this.stack = options.stack;
|
|
46
|
-
this.apiVersion = options.apiVersion ?? "2026-
|
|
111
|
+
this.apiVersion = options.apiVersion ?? "2026-07-23";
|
|
47
112
|
this.maxRetries = options.maxRetries ?? 6;
|
|
48
113
|
this.retryDelayMs = options.retryDelayMs ?? 100;
|
|
49
114
|
this.retryBudgetMs = options.retryBudgetMs ?? 60_000;
|
|
@@ -72,7 +137,6 @@ export class LbbClient {
|
|
|
72
137
|
this.fetchImpl = chosen;
|
|
73
138
|
this.context = new ContextNamespace(this);
|
|
74
139
|
this.search = new SearchNamespace(this);
|
|
75
|
-
this.indexes = new IndexNamespace(this);
|
|
76
140
|
this.entities = new EntityNamespace(this);
|
|
77
141
|
this.schema = new SchemaNamespace(this);
|
|
78
142
|
this.ontology = new OntologyNamespace(this);
|
|
@@ -174,6 +238,7 @@ export class LbbClient {
|
|
|
174
238
|
method,
|
|
175
239
|
headers,
|
|
176
240
|
body,
|
|
241
|
+
...(opts.duplex ? { duplex: opts.duplex } : {}),
|
|
177
242
|
};
|
|
178
243
|
const timeoutMs = opts.timeoutMs ?? this.timeoutMs;
|
|
179
244
|
const maxRetries = opts.maxRetries ?? this.maxRetries;
|
|
@@ -209,10 +274,16 @@ export class LbbClient {
|
|
|
209
274
|
maxAttempts: maxRetries + 1,
|
|
210
275
|
idempotencyKey: opts.idempotencyKey,
|
|
211
276
|
});
|
|
212
|
-
|
|
277
|
+
const requestInit = {
|
|
213
278
|
...init,
|
|
214
279
|
signal: controller?.signal ?? opts.signal,
|
|
215
|
-
}
|
|
280
|
+
};
|
|
281
|
+
// Keep FetchLike's long-standing string-body test-double contract while
|
|
282
|
+
// allowing this one endpoint to pass a native streaming body to fetch.
|
|
283
|
+
// Native browser/Node fetch implementations accept the extended shape;
|
|
284
|
+
// custom transports that need durable imports can inspect it at runtime.
|
|
285
|
+
const streamingFetch = this.fetchImpl;
|
|
286
|
+
response = await streamingFetch(url, requestInit);
|
|
216
287
|
text = await response.text();
|
|
217
288
|
}
|
|
218
289
|
catch (error) {
|
|
@@ -323,6 +394,12 @@ export class LbbClient {
|
|
|
323
394
|
idempotencyKey(prefix = "request") {
|
|
324
395
|
return this.mutationKey(prefix);
|
|
325
396
|
}
|
|
397
|
+
async requireCapability(capability) {
|
|
398
|
+
this.capabilities ??= this.request("GET", "/version").then((version) => new Set(version.capabilities));
|
|
399
|
+
if (!(await this.capabilities).has(capability)) {
|
|
400
|
+
throw new LbbCapabilityError(capability);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
326
403
|
// --- writes ---
|
|
327
404
|
/** Commit triplets and optional entity embeddings. Prefer `client.graph("main").facts.create(...)`. */
|
|
328
405
|
async commit(body, opts = {}) {
|
|
@@ -354,12 +431,10 @@ export class LbbClient {
|
|
|
354
431
|
* streamed request without a single oversized commit. Pass `lines` as an array
|
|
355
432
|
* (serialized to NDJSON here) or a pre-built NDJSON string.
|
|
356
433
|
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
*
|
|
361
|
-
* the throttle): import the whole dataset, index once. The response's `index`
|
|
362
|
-
* object reports whether the build ran or was skipped.
|
|
434
|
+
* A successful import durably enqueues one complete published-generation
|
|
435
|
+
* build after the final batch. It does not build index families or wait for
|
|
436
|
+
* visibility; the response's `published_generation` object carries the
|
|
437
|
+
* durable job and due sequence to observe.
|
|
363
438
|
*/
|
|
364
439
|
async import(lines, opts = {}) {
|
|
365
440
|
const ndjson = typeof lines === "string"
|
|
@@ -372,7 +447,6 @@ export class LbbClient {
|
|
|
372
447
|
batch: opts.batch,
|
|
373
448
|
strict: opts.strict,
|
|
374
449
|
observed_at: opts.observedAt,
|
|
375
|
-
index: opts.index,
|
|
376
450
|
},
|
|
377
451
|
idempotencyKey: opts.idempotencyKey ?? this.idempotencyKey("import"),
|
|
378
452
|
});
|
|
@@ -380,6 +454,72 @@ export class LbbClient {
|
|
|
380
454
|
// write→floor→read loop reads naturally after a bulk load.
|
|
381
455
|
return { ...response, commitSeq: response.committed_commit_seq ?? null };
|
|
382
456
|
}
|
|
457
|
+
/**
|
|
458
|
+
* Stream NDJSON into immutable storage and enqueue a durable import job.
|
|
459
|
+
*
|
|
460
|
+
* The idempotency key is mandatory and binds the key to the uploaded content.
|
|
461
|
+
* Streaming uploads are attempted once: a one-shot async iterator cannot be
|
|
462
|
+
* replayed safely by an automatic HTTP retry. Call this method again with a
|
|
463
|
+
* fresh iterable and the same key to perform an explicit idempotent replay.
|
|
464
|
+
*/
|
|
465
|
+
async submitImport(lines, opts) {
|
|
466
|
+
if (!opts?.idempotencyKey?.trim()) {
|
|
467
|
+
throw new TypeError("submitImport requires a non-empty idempotencyKey");
|
|
468
|
+
}
|
|
469
|
+
await this.requireCapability("durable_import_jobs_v1");
|
|
470
|
+
return this.request("POST", "/v1/graph/import-jobs", {
|
|
471
|
+
rawBody: durableImportBody(lines),
|
|
472
|
+
contentType: "application/x-ndjson",
|
|
473
|
+
duplex: "half",
|
|
474
|
+
query: {
|
|
475
|
+
batch: opts.batch,
|
|
476
|
+
strict: opts.strict,
|
|
477
|
+
observed_at: opts.observedAt,
|
|
478
|
+
},
|
|
479
|
+
idempotencyKey: opts.idempotencyKey,
|
|
480
|
+
maxRetries: 0,
|
|
481
|
+
retry: false,
|
|
482
|
+
signal: opts.signal,
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
async getImportJob(jobId) {
|
|
486
|
+
await this.requireCapability("durable_import_jobs_v1");
|
|
487
|
+
return this.request("GET", "/v1/graph/import-jobs", {
|
|
488
|
+
query: { job_id: jobId },
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
async cancelImportJob(jobId) {
|
|
492
|
+
await this.requireCapability("durable_import_jobs_v1");
|
|
493
|
+
return this.request("DELETE", "/v1/graph/import-jobs", {
|
|
494
|
+
query: { job_id: jobId },
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
async waitForImportJob(jobId, opts = {}) {
|
|
498
|
+
const pollIntervalMs = opts.pollIntervalMs ?? 1_000;
|
|
499
|
+
const timeoutMs = opts.timeoutMs ?? 0;
|
|
500
|
+
if (!Number.isFinite(pollIntervalMs) || pollIntervalMs < 0) {
|
|
501
|
+
throw new RangeError("pollIntervalMs must be a non-negative number");
|
|
502
|
+
}
|
|
503
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
504
|
+
throw new RangeError("timeoutMs must be a non-negative number");
|
|
505
|
+
}
|
|
506
|
+
const deadline = timeoutMs > 0 ? Date.now() + timeoutMs : undefined;
|
|
507
|
+
for (;;) {
|
|
508
|
+
if (opts.signal?.aborted) {
|
|
509
|
+
throw opts.signal.reason ?? new Error("request aborted");
|
|
510
|
+
}
|
|
511
|
+
const status = await this.getImportJob(jobId);
|
|
512
|
+
if (status.state === "succeeded" ||
|
|
513
|
+
status.state === "failed" ||
|
|
514
|
+
status.state === "cancelled") {
|
|
515
|
+
return status;
|
|
516
|
+
}
|
|
517
|
+
if (deadline !== undefined && Date.now() >= deadline) {
|
|
518
|
+
throw new Error(`timed out waiting for durable import job ${jobId}`);
|
|
519
|
+
}
|
|
520
|
+
await sleep(pollIntervalMs);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
383
523
|
/**
|
|
384
524
|
* Bulk-ingest N-Triples, Turtle, N-Quads, or TriG without client-side conversion. Resource-object
|
|
385
525
|
* triples become keyed Resource edges; literal-object triples become text
|
|
@@ -410,19 +550,6 @@ export class LbbClient {
|
|
|
410
550
|
idempotencyKey: opts.idempotencyKey ?? this.idempotencyKey("import-rdf"),
|
|
411
551
|
});
|
|
412
552
|
}
|
|
413
|
-
/** Export the snapshot-visible RDF projection as Turtle, N-Triples, TriG, or N-Quads. */
|
|
414
|
-
exportRdf(opts = {}) {
|
|
415
|
-
return this.request("GET", "/v1/graph/export/rdf", {
|
|
416
|
-
query: {
|
|
417
|
-
format: opts.format === "ntriples" ? "nt" : opts.format,
|
|
418
|
-
max_triples: opts.maxTriples,
|
|
419
|
-
as_of_valid_time: opts.asOfValidTime,
|
|
420
|
-
as_of_commit_seq: opts.asOfCommitSeq,
|
|
421
|
-
entailment: opts.entailment,
|
|
422
|
-
reason: opts.reason,
|
|
423
|
-
},
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
553
|
/**
|
|
427
554
|
* Retract specific edges and/or every edge touching given entities. Appends
|
|
428
555
|
* superseding retract events rather than deleting — history stays visible in an
|
|
@@ -640,23 +767,19 @@ export class LbbClient {
|
|
|
640
767
|
query: { kind: opts.kind, run: opts.run },
|
|
641
768
|
});
|
|
642
769
|
}
|
|
643
|
-
/**
|
|
644
|
-
* Champion vs challenger retrieval over one pinned snapshot. Returns
|
|
645
|
-
* promotion evidence (hit-rate@k, latency, overlap); never promotes.
|
|
646
|
-
*/
|
|
647
|
-
shadowEval(body) {
|
|
648
|
-
return this.request("POST", "/v1/models/shadow-eval", { body });
|
|
649
|
-
}
|
|
650
|
-
/**
|
|
651
|
-
* Execution-verified QA probes generated from the graph's current edges —
|
|
652
|
-
* labels are the executed projections, so they are verified by construction.
|
|
653
|
-
* Feeds `shadowEval` directly.
|
|
654
|
-
*/
|
|
770
|
+
/** Execution-verified QA probes generated from the graph's current edges. */
|
|
655
771
|
syntheticEval(opts = {}) {
|
|
656
772
|
return this.request("GET", "/v1/models/synthetic-eval", {
|
|
657
773
|
query: { limit: opts.limit },
|
|
658
774
|
});
|
|
659
775
|
}
|
|
776
|
+
/**
|
|
777
|
+
* Compare champion and challenger retrieval over one pinned published
|
|
778
|
+
* snapshot. The endpoint returns promotion evidence but never promotes.
|
|
779
|
+
*/
|
|
780
|
+
shadowEval(body) {
|
|
781
|
+
return this.request("POST", "/v1/models/shadow-eval", { body });
|
|
782
|
+
}
|
|
660
783
|
/** The doubling retrain policy: is a retrain due for this model kind? */
|
|
661
784
|
modelCadence(opts) {
|
|
662
785
|
return this.request("GET", "/v1/models/cadence", {
|
|
@@ -682,18 +805,6 @@ export class LbbClient {
|
|
|
682
805
|
setTrainingConfig(body) {
|
|
683
806
|
return this.request("POST", "/v1/models/training-config", { body });
|
|
684
807
|
}
|
|
685
|
-
/**
|
|
686
|
-
* Verdict on an ask (`accepted` | `rejected` | `corrected` + the right
|
|
687
|
-
* plan), joined to the ask's trace by `ask_id` — the planner fine-tune's
|
|
688
|
-
* explicit feedback capture. `accepted: false` in the response means
|
|
689
|
-
* signal capture is off on this deployment (the contract is identical).
|
|
690
|
-
*/
|
|
691
|
-
askFeedback(body, opts = {}) {
|
|
692
|
-
return this.request("POST", "/v1/ask/feedback", {
|
|
693
|
-
body,
|
|
694
|
-
idempotencyKey: opts.idempotencyKey ?? this.idempotencyKey("ask-feedback"),
|
|
695
|
-
});
|
|
696
|
-
}
|
|
697
808
|
ingestSignals(body, opts = {}) {
|
|
698
809
|
return this.request("POST", "/v1/signals", {
|
|
699
810
|
body,
|
|
@@ -718,39 +829,25 @@ export class LbbClient {
|
|
|
718
829
|
],
|
|
719
830
|
}, opts);
|
|
720
831
|
}
|
|
721
|
-
/**
|
|
722
|
-
* The planner fine-tune's training feed: accepted/corrected feedback
|
|
723
|
-
* joined to its traces (signals ≤ the split pin), topped up with
|
|
724
|
-
* execution-verified synthetic plans.
|
|
725
|
-
*/
|
|
832
|
+
/** Planner training examples at or before an optional signal split. */
|
|
726
833
|
plannerDataset(opts = {}) {
|
|
727
834
|
return this.request("GET", "/v1/models/planner-dataset", {
|
|
728
835
|
query: { limit: opts.limit, split_seq: opts.splitSeq },
|
|
729
836
|
});
|
|
730
837
|
}
|
|
731
|
-
/**
|
|
732
|
-
* The DPO pass's training feed: preference pairs from corrected verdicts,
|
|
733
|
-
* paired rejections, and synthetic corrupted-slot pairs.
|
|
734
|
-
*/
|
|
838
|
+
/** Planner preference pairs at or before an optional signal split. */
|
|
735
839
|
plannerPreferenceDataset(opts = {}) {
|
|
736
840
|
return this.request("GET", "/v1/models/planner-preference-dataset", {
|
|
737
841
|
query: { limit: opts.limit, split_seq: opts.splitSeq },
|
|
738
842
|
});
|
|
739
843
|
}
|
|
740
|
-
/**
|
|
741
|
-
* The suggest-ranker trainer's probe feed: `suggestion_adopted` signals
|
|
742
|
-
* (typed prefix + adopted text) ≤ the split pin, topped up with
|
|
743
|
-
* execution-verified synthetic vocabulary pairs.
|
|
744
|
-
*/
|
|
844
|
+
/** Suggest-ranker examples at or before an optional signal split. */
|
|
745
845
|
suggestDataset(opts = {}) {
|
|
746
846
|
return this.request("GET", "/v1/models/suggest-dataset", {
|
|
747
847
|
query: { limit: opts.limit, split_seq: opts.splitSeq },
|
|
748
848
|
});
|
|
749
849
|
}
|
|
750
|
-
/**
|
|
751
|
-
* The extractor fine-tune's training feed: EPISODE transcripts joined to
|
|
752
|
-
* the facts the observe pipeline committed from them.
|
|
753
|
-
*/
|
|
850
|
+
/** Extractor examples at or before an optional signal split. */
|
|
754
851
|
extractorDataset(opts = {}) {
|
|
755
852
|
return this.request("GET", "/v1/models/extractor-dataset", {
|
|
756
853
|
query: { limit: opts.limit, split_seq: opts.splitSeq },
|
|
@@ -768,8 +865,7 @@ export class LbbClient {
|
|
|
768
865
|
}
|
|
769
866
|
/**
|
|
770
867
|
* Promote a finished `planner_lora` training run: gated on held-out slot
|
|
771
|
-
* exactness
|
|
772
|
-
* then serves.
|
|
868
|
+
* exactness and recorded as a `kind=planner` training run.
|
|
773
869
|
*/
|
|
774
870
|
promotePlanner(opts) {
|
|
775
871
|
return this.request("POST", "/v1/models/promote-planner", {
|
|
@@ -800,37 +896,18 @@ export class LbbClient {
|
|
|
800
896
|
suggest(body) {
|
|
801
897
|
return this.request("POST", "/v1/search/suggest", { body });
|
|
802
898
|
}
|
|
803
|
-
/**
|
|
804
|
-
* Snap free text to the nearest real vocabulary item. Embedding cosine
|
|
805
|
-
* on a managed graph, else lexical; never fabricates a term.
|
|
806
|
-
*/
|
|
899
|
+
/** Snap free text to the nearest term in the pinned published vocabulary. */
|
|
807
900
|
resolveTerm(body) {
|
|
808
901
|
return this.request("POST", "/v1/search/resolve-term", { body });
|
|
809
902
|
}
|
|
810
|
-
/**
|
|
811
|
-
* Ground a natural-language question to the graph's real vocabulary, retrieve
|
|
812
|
-
* against the pinned snapshot, and answer with citations (`/v1/ask`).
|
|
813
|
-
*/
|
|
814
|
-
ask(body) {
|
|
815
|
-
return this.request("POST", "/v1/ask", { body });
|
|
816
|
-
}
|
|
817
|
-
/**
|
|
818
|
-
* Name the relation between two entities (`/v1/decode`): the DB narrows the
|
|
819
|
-
* candidates to the type pair's admissible relations, answers alone
|
|
820
|
-
* when the pair forces a single relation, and otherwise decodes it with the
|
|
821
|
-
* graph-native fine-tuned model — the "DB narrows, cheap model decodes" call.
|
|
822
|
-
*/
|
|
903
|
+
/** Decode a relation from the graph's admissible published vocabulary. */
|
|
823
904
|
decode(body) {
|
|
824
905
|
return this.request("POST", "/v1/decode", { body });
|
|
825
906
|
}
|
|
826
|
-
/**
|
|
827
|
-
* Report which completion mechanisms will carry on this graph:
|
|
828
|
-
* signature sparsity, name semantics, sampled narrowing recall, and a
|
|
829
|
-
* narrow / narrow+finetune / lexical-first recommendation.
|
|
830
|
-
*/
|
|
907
|
+
/** Report completion strategy fitness for the pinned published graph. */
|
|
831
908
|
groundability(opts = {}) {
|
|
832
909
|
return this.request("GET", "/v1/graph/groundability", {
|
|
833
|
-
query: opts.sample
|
|
910
|
+
query: opts.sample == null ? undefined : { sample: opts.sample },
|
|
834
911
|
});
|
|
835
912
|
}
|
|
836
913
|
/**
|
|
@@ -880,7 +957,6 @@ export class LbbClient {
|
|
|
880
957
|
name: opts.name,
|
|
881
958
|
relations: opts.relations?.join(","),
|
|
882
959
|
as_of: opts.asOf,
|
|
883
|
-
indexed: opts.indexed,
|
|
884
960
|
},
|
|
885
961
|
});
|
|
886
962
|
}
|
|
@@ -920,39 +996,11 @@ export class LbbClient {
|
|
|
920
996
|
},
|
|
921
997
|
});
|
|
922
998
|
}
|
|
923
|
-
/**
|
|
924
|
-
* Paged edge listing. Scope to one node with `id` (or `type`+`name`) and a
|
|
925
|
-
* `direction` (`out`/`in`/`both`) to walk **every** edge of a high-degree node
|
|
926
|
-
* — `entityDetail` returns the full set but is awkward to page; this carries
|
|
927
|
-
* `offset`/`limit` and reports `total_count`. Optional `relation`/`q` filters
|
|
928
|
-
* and an `asOf`/`asOfCommitSeq` snapshot pin. Each row carries `valid_time`, so
|
|
929
|
-
* the page is enough to reconstruct a per-edge timeline.
|
|
930
|
-
*/
|
|
931
|
-
graphEdges(opts = {}) {
|
|
932
|
-
return this.request("GET", "/v1/graph/edges", {
|
|
933
|
-
query: {
|
|
934
|
-
id: opts.id,
|
|
935
|
-
type: opts.type,
|
|
936
|
-
name: opts.name,
|
|
937
|
-
direction: opts.direction,
|
|
938
|
-
relation: opts.relation,
|
|
939
|
-
q: opts.q,
|
|
940
|
-
limit: opts.limit,
|
|
941
|
-
cursor: opts.cursor,
|
|
942
|
-
offset: opts.offset,
|
|
943
|
-
as_of: opts.asOf,
|
|
944
|
-
as_of_commit_seq: opts.asOfCommitSeq,
|
|
945
|
-
},
|
|
946
|
-
});
|
|
947
|
-
}
|
|
948
999
|
/**
|
|
949
1000
|
* Page through every row of a list endpoint, following `next_cursor` until
|
|
950
1001
|
* exhausted. Pass a fetcher that takes a cursor and returns a
|
|
951
1002
|
* {@link ListResponse}:
|
|
952
|
-
*
|
|
953
|
-
* for await (const e of client.listAll((cursor) =>
|
|
954
|
-
* client.entities.list({ cursor, fields: "title" }))) { … }
|
|
955
|
-
* ```
|
|
1003
|
+
* The caller supplies a bounded collection endpoint and its cursor.
|
|
956
1004
|
*/
|
|
957
1005
|
async *listAll(fetchPage) {
|
|
958
1006
|
let cursor;
|
|
@@ -982,10 +1030,6 @@ export class LbbClient {
|
|
|
982
1030
|
why(body) {
|
|
983
1031
|
return this.request("POST", "/v1/query/why", { body });
|
|
984
1032
|
}
|
|
985
|
-
/** SHACL-style shape/pattern query. */
|
|
986
|
-
shacl(body) {
|
|
987
|
-
return this.request("POST", "/v1/query/shacl", { body });
|
|
988
|
-
}
|
|
989
1033
|
/**
|
|
990
1034
|
* SPARQL-subset SELECT/ASK/aggregate query (FILTER, HAVING, ORDER BY, ASK,
|
|
991
1035
|
* COUNT/SUM/AVG/MIN/MAX). GROUP BY is not limited to entity identity:
|
|
@@ -1028,36 +1072,6 @@ export class LbbClient {
|
|
|
1028
1072
|
analytics(body) {
|
|
1029
1073
|
return this.request("POST", "/v1/query/analytics", { body });
|
|
1030
1074
|
}
|
|
1031
|
-
/**
|
|
1032
|
-
* Run inference rules (SHACL-AF `sh:TripleRule` shape) to a bounded fixpoint
|
|
1033
|
-
* and return the derived edges as a **preview** — derived facts are never
|
|
1034
|
-
* written to the asserted graph. Each rule is a BGP `body`/`where` plus a
|
|
1035
|
-
* `head` triple template instantiated per binding.
|
|
1036
|
-
*/
|
|
1037
|
-
infer(body) {
|
|
1038
|
-
return this.request("POST", "/v1/inference/run", { body });
|
|
1039
|
-
}
|
|
1040
|
-
/**
|
|
1041
|
-
* Define (replace) the versioned rule set stored on the scoped graph branch.
|
|
1042
|
-
* The stored set is what SHACL `include_derived` and `infer` use when a
|
|
1043
|
-
* request carries no inline rules. Returns the new `rules_version`.
|
|
1044
|
-
*/
|
|
1045
|
-
defineRules(body) {
|
|
1046
|
-
return this.request("POST", "/v1/inference/rules", { body });
|
|
1047
|
-
}
|
|
1048
|
-
/** The rule set stored on the scoped graph branch (version + rules). */
|
|
1049
|
-
graphRules() {
|
|
1050
|
-
return this.request("GET", "/v1/inference/rules");
|
|
1051
|
-
}
|
|
1052
|
-
/**
|
|
1053
|
-
* Derive edges from calibrated retrieval matches (preview): each
|
|
1054
|
-
* candidate scored `P >= threshold` becomes a derived edge `(anchor, relation,
|
|
1055
|
-
* matched)` with a typed `Retrieval` provenance leaf. Pass either explicit
|
|
1056
|
-
* `candidates` or a `query` the server runs as BM25 entity retrieval.
|
|
1057
|
-
*/
|
|
1058
|
-
retrievalPremises(body) {
|
|
1059
|
-
return this.request("POST", "/v1/inference/retrieval-premises", { body });
|
|
1060
|
-
}
|
|
1061
1075
|
// --- ontology ---
|
|
1062
1076
|
/**
|
|
1063
1077
|
* The active ontology (entity types and relations) for the scoped graph.
|
|
@@ -1074,12 +1088,13 @@ export class LbbClient {
|
|
|
1074
1088
|
* Audit the current snapshot against the ontology's *implied* constraints —
|
|
1075
1089
|
* capped `cardinality` derived as `sh:maxCount` — returning a SHACL-shaped
|
|
1076
1090
|
* report. Whole-snapshot and never blocks a write. Unlike
|
|
1077
|
-
*
|
|
1078
|
-
*
|
|
1079
|
-
* {@link ontologyView} for which decorations are enforced.
|
|
1091
|
+
* The report is referenced by the pinned published read root and carries its
|
|
1092
|
+
* own validation watermark and ontology/shapes provenance.
|
|
1080
1093
|
*/
|
|
1081
|
-
ontologyConformance() {
|
|
1082
|
-
return this.request("GET", "/v1/ontology/conformance"
|
|
1094
|
+
ontologyConformance(opts) {
|
|
1095
|
+
return this.request("GET", "/v1/ontology/conformance", {
|
|
1096
|
+
query: { consistency: this.resolveConsistency(opts) },
|
|
1097
|
+
});
|
|
1083
1098
|
}
|
|
1084
1099
|
/** Discover ontology concepts, terms, and relations. */
|
|
1085
1100
|
ontologySearch(body) {
|
|
@@ -1106,75 +1121,6 @@ export class LbbClient {
|
|
|
1106
1121
|
induceOntology(body) {
|
|
1107
1122
|
return this.request("POST", "/v1/ontology/induce", { body, retry: true });
|
|
1108
1123
|
}
|
|
1109
|
-
// --- index lifecycle ---
|
|
1110
|
-
/**
|
|
1111
|
-
* Build default ANN + BM25 indexes. With `{ background: true }` the build
|
|
1112
|
-
* runs detached on the server and the call returns immediately — use it for
|
|
1113
|
-
* large corpora whose synchronous build would exceed a fronting gateway's
|
|
1114
|
-
* timeout (a 504), then poll `metadata()` for completion.
|
|
1115
|
-
*/
|
|
1116
|
-
indexBuild(opts = {}) {
|
|
1117
|
-
return this.request("POST", "/v1/index/build", {
|
|
1118
|
-
query: { background: opts.background || undefined },
|
|
1119
|
-
});
|
|
1120
|
-
}
|
|
1121
|
-
/**
|
|
1122
|
-
* Build BM25, ANN/vector, and adjacency index families. With
|
|
1123
|
-
* `{ background: true }` the build runs detached on the server and the call
|
|
1124
|
-
* returns immediately — use it for large corpora whose synchronous build would
|
|
1125
|
-
* exceed a fronting gateway's timeout, then poll `metadata()` for completion.
|
|
1126
|
-
*/
|
|
1127
|
-
indexRun(opts = {}) {
|
|
1128
|
-
return this.request("POST", "/v1/index/run", {
|
|
1129
|
-
query: { background: opts.background || undefined },
|
|
1130
|
-
});
|
|
1131
|
-
}
|
|
1132
|
-
/** Submit a durable full-index build. Requires a reconnect-safe idempotency key. */
|
|
1133
|
-
indexSubmit(body = {}, opts) {
|
|
1134
|
-
return this.request("POST", "/v1/index/jobs", {
|
|
1135
|
-
body,
|
|
1136
|
-
idempotencyKey: opts.idempotencyKey,
|
|
1137
|
-
});
|
|
1138
|
-
}
|
|
1139
|
-
/** Poll a durable full-index build. */
|
|
1140
|
-
indexJob(jobId) {
|
|
1141
|
-
return this.request("GET", "/v1/index/jobs", { query: { job_id: jobId } });
|
|
1142
|
-
}
|
|
1143
|
-
/** Cancel a durable full-index build. Repeated cancellation returns its current terminal status. */
|
|
1144
|
-
cancelIndexJob(jobId) {
|
|
1145
|
-
return this.request("DELETE", "/v1/index/jobs", {
|
|
1146
|
-
query: { job_id: jobId },
|
|
1147
|
-
});
|
|
1148
|
-
}
|
|
1149
|
-
/** Append a BM25 delta segment for the unindexed WAL tail. */
|
|
1150
|
-
indexDelta() {
|
|
1151
|
-
return this.request("POST", "/v1/index/delta");
|
|
1152
|
-
}
|
|
1153
|
-
/** Preview or delete superseded persisted index runs. */
|
|
1154
|
-
indexGc(opts = {}) {
|
|
1155
|
-
return this.request("POST", "/v1/index/gc", {
|
|
1156
|
-
query: { keep_runs: opts.keepRuns, dry_run: opts.dryRun },
|
|
1157
|
-
});
|
|
1158
|
-
}
|
|
1159
|
-
/** Submit durable, cancellable index garbage collection. */
|
|
1160
|
-
indexGcSubmit(body = {}, opts) {
|
|
1161
|
-
return this.request("POST", "/v1/index/gc-jobs", {
|
|
1162
|
-
body,
|
|
1163
|
-
idempotencyKey: opts.idempotencyKey,
|
|
1164
|
-
});
|
|
1165
|
-
}
|
|
1166
|
-
/** Poll exact planning/deletion progress for durable index garbage collection. */
|
|
1167
|
-
indexGcJob(jobId) {
|
|
1168
|
-
return this.request("GET", "/v1/index/gc-jobs", {
|
|
1169
|
-
query: { job_id: jobId },
|
|
1170
|
-
});
|
|
1171
|
-
}
|
|
1172
|
-
/** Cancel durable index garbage collection. */
|
|
1173
|
-
cancelIndexGcJob(jobId) {
|
|
1174
|
-
return this.request("DELETE", "/v1/index/gc-jobs", {
|
|
1175
|
-
query: { job_id: jobId },
|
|
1176
|
-
});
|
|
1177
|
-
}
|
|
1178
1124
|
/** Fold the WAL tail into snapshot segments. */
|
|
1179
1125
|
compact(opts = {}) {
|
|
1180
1126
|
return this.request("POST", "/v1/graph/compact", {
|
|
@@ -1189,13 +1135,11 @@ export class LbbClient {
|
|
|
1189
1135
|
status() {
|
|
1190
1136
|
return this.request("GET", "/v1/status");
|
|
1191
1137
|
}
|
|
1192
|
-
/** Graph footprint, WAL tail, and index coverage.
|
|
1138
|
+
/** Graph footprint, WAL tail, and published-index coverage. */
|
|
1193
1139
|
metadata(opts = {}) {
|
|
1194
1140
|
return this.request("GET", "/v1/graph/metadata", {
|
|
1195
1141
|
query: {
|
|
1196
|
-
include_objects: opts.includeObjects,
|
|
1197
1142
|
include_indexes: opts.includeIndexes,
|
|
1198
|
-
include_temporal_coverage: opts.includeTemporalCoverage,
|
|
1199
1143
|
},
|
|
1200
1144
|
});
|
|
1201
1145
|
}
|
|
@@ -1236,6 +1180,10 @@ export class LbbClient {
|
|
|
1236
1180
|
query: this.readConsistencyQuery(opts),
|
|
1237
1181
|
});
|
|
1238
1182
|
}
|
|
1183
|
+
/** Pinned published read root and its query/conformance lag against one coherent head. */
|
|
1184
|
+
readSnapshot() {
|
|
1185
|
+
return this.request("GET", "/v1/graph/read-snapshot");
|
|
1186
|
+
}
|
|
1239
1187
|
/** List the graphs (and branches) under the scoped tenant. */
|
|
1240
1188
|
listGraphs() {
|
|
1241
1189
|
return this.request("GET", "/v1/graphs");
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { LbbClient, LbbError, parseSparqlResults } from "./client.js";
|
|
2
|
-
export type { LbbClientOptions, CallOptions, RequestOptions,
|
|
1
|
+
export { LbbCapabilityError, LbbClient, LbbError, parseSparqlResults, } from "./client.js";
|
|
2
|
+
export type { DurableImportLine, DurableImportSource, 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";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { LbbClient, LbbError, parseSparqlResults } from "./client.js";
|
|
1
|
+
export { LbbCapabilityError, LbbClient, LbbError, parseSparqlResults, } from "./client.js";
|