@littlebigbrain/mcp 0.5.2 → 0.7.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 +5 -7
- package/dist/http-server.d.ts +0 -1
- package/dist/http-server.js +0 -1
- package/dist/metadata-pages.d.ts +0 -2
- package/dist/metadata-pages.js +2 -12
- package/dist/rdf-tool.js +2 -3
- package/dist/stdio.js +1 -2
- package/dist/tool-contracts.js +2 -56
- package/dist/tool-runtime.js +24 -51
- package/dist/tools.js +26 -165
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -64,8 +64,8 @@ Requires Node.js 18+. Copy the complete endpoint and a stack API key from
|
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
The client starts the server and communicates through standard input and output
|
|
67
|
-
(stdio). Keep the key in your local configuration. Set `LBB_GRAPH`
|
|
68
|
-
|
|
67
|
+
(stdio). Keep the key in your local configuration. Set `LBB_GRAPH` to change
|
|
68
|
+
the default graph from `main`.
|
|
69
69
|
|
|
70
70
|
## Run a first query
|
|
71
71
|
|
|
@@ -112,7 +112,7 @@ its original identifiers; inspect it with SPARQL when choosing query predicates.
|
|
|
112
112
|
|
|
113
113
|
| Tool | Purpose |
|
|
114
114
|
| --- | --- |
|
|
115
|
-
| `lbb_inspect` | Read the schema, graph status,
|
|
115
|
+
| `lbb_inspect` | Read the schema, graph status, and entities. |
|
|
116
116
|
| `lbb_query` | Run SPARQL queries, search by meaning, or request summary statistics. |
|
|
117
117
|
| `lbb_rdf` | Import RDF documents or add facts with SPARQL `INSERT DATA`. |
|
|
118
118
|
| `lbb_embeddings` | Inspect search setup and preview the text to embed. |
|
|
@@ -120,8 +120,6 @@ its original identifiers; inspect it with SPARQL when choosing query predicates.
|
|
|
120
120
|
| `lbb_embeddings_delete` | Delete an embedding and its stored vectors. |
|
|
121
121
|
| `lbb_commit` | Write or retract JSON facts, or record search feedback. |
|
|
122
122
|
| `lbb_configure` | Define record types and relationships, or publish validation rules. |
|
|
123
|
-
| `lbb_branch` | Create branches and merge reviewed changes. |
|
|
124
|
-
| `lbb_observe` | Store conversation episodes and reviewed facts extracted from them. |
|
|
125
123
|
| `lbb_evals` | Label query results and check whether later queries return the expected answers. |
|
|
126
124
|
| `lbb_models` | Compare retrieval settings and read model training datasets. |
|
|
127
125
|
|
|
@@ -130,8 +128,8 @@ for embedding setup. To define constraints with the Shapes Constraint Language
|
|
|
130
128
|
(SHACL), see [query and validation](https://docs.littlebigbrain.com/guides/sparql-and-shacl/).
|
|
131
129
|
|
|
132
130
|
RDF imports and JSON facts use different write workflows. A graph first written
|
|
133
|
-
through `lbb_rdf` does not accept JSON fact writes through `lbb_commit
|
|
134
|
-
|
|
131
|
+
through `lbb_rdf` does not accept JSON fact writes through `lbb_commit`. Choose
|
|
132
|
+
the workflow when creating the graph. RDF updates
|
|
135
133
|
support additive `INSERT DATA`;
|
|
136
134
|
see the [RDF guide](https://docs.littlebigbrain.com/guides/load-rdf/) for format and
|
|
137
135
|
update limits.
|
package/dist/http-server.d.ts
CHANGED
package/dist/http-server.js
CHANGED
|
@@ -150,7 +150,6 @@ export function createMcpHttpServer(options) {
|
|
|
150
150
|
baseUrl,
|
|
151
151
|
apiKey,
|
|
152
152
|
graph: url.searchParams.get("graph") ?? undefined,
|
|
153
|
-
branch: url.searchParams.get("branch") ?? undefined,
|
|
154
153
|
};
|
|
155
154
|
const client = options.clientFactory
|
|
156
155
|
? options.clientFactory(clientOptions)
|
package/dist/metadata-pages.d.ts
CHANGED
|
@@ -4,7 +4,6 @@ import { metadataPageSchema } from "./tool-contracts.js";
|
|
|
4
4
|
type Request = z.infer<z.ZodObject<typeof metadataPageSchema>> & {
|
|
5
5
|
action: "ontology" | "schema";
|
|
6
6
|
graph?: string;
|
|
7
|
-
branch?: string;
|
|
8
7
|
};
|
|
9
8
|
/** Stateless pagination of complete entries, including their full nested values.
|
|
10
9
|
* A digest rejects mixed-version reads instead of skipping/repeating definitions
|
|
@@ -24,7 +23,6 @@ export declare function metadataPage(client: LbbClient, args: Request): Promise<
|
|
|
24
23
|
next: {
|
|
25
24
|
action: "ontology" | "schema";
|
|
26
25
|
graph: string | undefined;
|
|
27
|
-
branch: string | undefined;
|
|
28
26
|
section: string | undefined;
|
|
29
27
|
page_size: number;
|
|
30
28
|
cursor: string;
|
package/dist/metadata-pages.js
CHANGED
|
@@ -7,7 +7,6 @@ const cursorSchema = z
|
|
|
7
7
|
v: z.literal(1),
|
|
8
8
|
action: z.enum(["ontology", "schema"]),
|
|
9
9
|
graph: z.string().optional(),
|
|
10
|
-
branch: z.string().optional(),
|
|
11
10
|
section: z.string().optional(),
|
|
12
11
|
page_size: z.number().int().min(1).max(500),
|
|
13
12
|
offset: z.number().int().nonnegative().safe(),
|
|
@@ -27,23 +26,16 @@ export async function metadataPage(client, args) {
|
|
|
27
26
|
catch {
|
|
28
27
|
throw new Error("invalid lbb_inspect cursor; restart without cursor");
|
|
29
28
|
}
|
|
30
|
-
for (const key of [
|
|
31
|
-
"action",
|
|
32
|
-
"graph",
|
|
33
|
-
"branch",
|
|
34
|
-
"section",
|
|
35
|
-
"page_size",
|
|
36
|
-
]) {
|
|
29
|
+
for (const key of ["action", "graph", "section", "page_size"]) {
|
|
37
30
|
if (args[key] !== undefined && args[key] !== cursor[key]) {
|
|
38
31
|
throw new Error(`cursor ${key} does not match the supplied ${key}`);
|
|
39
32
|
}
|
|
40
33
|
}
|
|
41
34
|
}
|
|
42
35
|
const graph = cursor?.graph ?? args.graph;
|
|
43
|
-
const branch = cursor?.branch ?? args.branch;
|
|
44
36
|
const section = cursor?.section ?? args.section;
|
|
45
37
|
const pageSize = cursor?.page_size ?? args.page_size ?? 50;
|
|
46
|
-
const target = client.withScope({ graph
|
|
38
|
+
const target = client.withScope({ graph });
|
|
47
39
|
const value = (args.action === "ontology"
|
|
48
40
|
? await target.ontologyView({ counts: true })
|
|
49
41
|
: await target.schema.view());
|
|
@@ -62,7 +54,6 @@ export async function metadataPage(client, args) {
|
|
|
62
54
|
v: 1,
|
|
63
55
|
action: args.action,
|
|
64
56
|
graph,
|
|
65
|
-
branch,
|
|
66
57
|
section,
|
|
67
58
|
page_size: pageSize,
|
|
68
59
|
fingerprint,
|
|
@@ -94,7 +85,6 @@ export async function metadataPage(client, args) {
|
|
|
94
85
|
? {
|
|
95
86
|
action: args.action,
|
|
96
87
|
graph,
|
|
97
|
-
branch,
|
|
98
88
|
section,
|
|
99
89
|
page_size: pageSize,
|
|
100
90
|
cursor: Buffer.from(JSON.stringify({
|
package/dist/rdf-tool.js
CHANGED
|
@@ -49,13 +49,12 @@ export function registerRdfTool(server, client) {
|
|
|
49
49
|
return errorResult(parsed.error);
|
|
50
50
|
const args = parsed.data;
|
|
51
51
|
return run(client, `lbb_rdf.${args.action}`, args.detail, async () => {
|
|
52
|
-
const target = scoped(client, args.graph
|
|
52
|
+
const target = scoped(client, args.graph);
|
|
53
53
|
const { idempotency_key } = args;
|
|
54
54
|
const operation = { ...args };
|
|
55
55
|
delete operation.detail;
|
|
56
56
|
delete operation.idempotency_key;
|
|
57
|
-
const key = idempotency_key ??
|
|
58
|
-
contentHashKey({ graph: args.graph, branch: args.branch }, operation);
|
|
57
|
+
const key = idempotency_key ?? contentHashKey({ graph: args.graph }, operation);
|
|
59
58
|
if (args.action === "import") {
|
|
60
59
|
return target.importRdf(args.source, {
|
|
61
60
|
format: args.format ?? "turtle",
|
package/dist/stdio.js
CHANGED
|
@@ -12,7 +12,7 @@ const BASE_URL_HELP = "LBB_BASE_URL is required. Copy endpoint_url from your Lit
|
|
|
12
12
|
*
|
|
13
13
|
* LBB_BASE_URL (required for tool calls; copy endpoint_url from the stack Connect page)
|
|
14
14
|
* LBB_API_KEY stack API key (lbb_sk_live_…) or single-mode token
|
|
15
|
-
* LBB_GRAPH
|
|
15
|
+
* LBB_GRAPH (optional; server defaults to main)
|
|
16
16
|
*
|
|
17
17
|
* The base URL is required lazily, at the first tool invocation, not at
|
|
18
18
|
* process start: MCP hosts launch servers to complete the initialize
|
|
@@ -44,7 +44,6 @@ async function main() {
|
|
|
44
44
|
baseUrl,
|
|
45
45
|
apiKey: process.env.LBB_API_KEY,
|
|
46
46
|
graph: process.env.LBB_GRAPH,
|
|
47
|
-
branch: process.env.LBB_BRANCH,
|
|
48
47
|
})
|
|
49
48
|
: unconfiguredClient();
|
|
50
49
|
const server = buildLbbServer(client);
|
package/dist/tool-contracts.js
CHANGED
|
@@ -40,10 +40,6 @@ export const graphScope = {
|
|
|
40
40
|
.string()
|
|
41
41
|
.optional()
|
|
42
42
|
.describe("Graph to target; defaults to the connection's graph"),
|
|
43
|
-
branch: z
|
|
44
|
-
.string()
|
|
45
|
-
.optional()
|
|
46
|
-
.describe("Branch to target; defaults to the connection's branch"),
|
|
47
43
|
};
|
|
48
44
|
export const jsonObjectSchema = z.record(z.string(), z.unknown());
|
|
49
45
|
export const jsonObjectArraySchema = z.array(jsonObjectSchema);
|
|
@@ -375,56 +371,7 @@ export const inspectInputSchema = z.discriminatedUnion("action", [
|
|
|
375
371
|
.int()
|
|
376
372
|
.nonnegative()
|
|
377
373
|
.optional()
|
|
378
|
-
.describe("Snapshot pin: reproduce the node
|
|
379
|
-
...readScope,
|
|
380
|
-
})
|
|
381
|
-
.strict(),
|
|
382
|
-
z
|
|
383
|
-
.object({
|
|
384
|
-
action: z.literal("state"),
|
|
385
|
-
entity_type: z.string(),
|
|
386
|
-
name: z.string(),
|
|
387
|
-
relation: z.string().optional(),
|
|
388
|
-
as_of: z.string().optional(),
|
|
389
|
-
as_of_commit_seq: z
|
|
390
|
-
.number()
|
|
391
|
-
.int()
|
|
392
|
-
.nonnegative()
|
|
393
|
-
.optional()
|
|
394
|
-
.describe("Snapshot pin: reproduce the state as of this commit_seq, hiding later commits. Errors if past head."),
|
|
395
|
-
...readScope,
|
|
396
|
-
})
|
|
397
|
-
.strict(),
|
|
398
|
-
z
|
|
399
|
-
.object({
|
|
400
|
-
action: z.literal("history"),
|
|
401
|
-
entity_type: z.string(),
|
|
402
|
-
name: z.string(),
|
|
403
|
-
relation: z.string().optional(),
|
|
404
|
-
...readScope,
|
|
405
|
-
})
|
|
406
|
-
.strict(),
|
|
407
|
-
z
|
|
408
|
-
.object({
|
|
409
|
-
action: z.literal("why"),
|
|
410
|
-
source_type: z.string(),
|
|
411
|
-
source_name: z.string(),
|
|
412
|
-
relation: z.string(),
|
|
413
|
-
target_type: z.string(),
|
|
414
|
-
target_name: z.string(),
|
|
415
|
-
...readScope,
|
|
416
|
-
})
|
|
417
|
-
.strict(),
|
|
418
|
-
z
|
|
419
|
-
.object({
|
|
420
|
-
action: z.literal("transitions"),
|
|
421
|
-
entity_type: z.string(),
|
|
422
|
-
name: z.string(),
|
|
423
|
-
relation: z
|
|
424
|
-
.string()
|
|
425
|
-
.describe("State/status relation to trace, e.g. IN_STAGE or HAS_STATUS"),
|
|
426
|
-
as_of: z.string().optional(),
|
|
427
|
-
as_of_commit_seq: z.number().int().nonnegative().optional(),
|
|
374
|
+
.describe("Snapshot pin: reproduce the node's attributes and relationships as of this commit_seq."),
|
|
428
375
|
...readScope,
|
|
429
376
|
})
|
|
430
377
|
.strict(),
|
|
@@ -576,7 +523,6 @@ export const configureInputSchema = z.discriminatedUnion("action", [
|
|
|
576
523
|
.optional()
|
|
577
524
|
.describe("Preview the exact definition without creating a graph or writing metadata."),
|
|
578
525
|
graph: z.string().describe("Graph to create or redefine"),
|
|
579
|
-
branch: graphScope.branch,
|
|
580
526
|
entity_types: z.array(z.union([z.string(), jsonObjectSchema])).optional(),
|
|
581
527
|
relations: z.array(z.union([z.string(), jsonObjectSchema])).optional(),
|
|
582
528
|
source: z.string().optional(),
|
|
@@ -627,7 +573,7 @@ export const configureInputSchema = z.discriminatedUnion("action", [
|
|
|
627
573
|
* rejects as `Expected object, received string`.
|
|
628
574
|
*
|
|
629
575
|
* Flatten the union into a single ZodObject purely for advertisement and
|
|
630
|
-
* transport: the discriminant becomes an enum, every
|
|
576
|
+
* transport: the discriminant becomes an enum, every variant field is merged in
|
|
631
577
|
* as optional, and unknown keys pass through. Each handler still `safeParse`s the
|
|
632
578
|
* raw args against the original strict union before dispatching, so per-variant
|
|
633
579
|
* required/forbidden fields are enforced exactly as before.
|
package/dist/tool-runtime.js
CHANGED
|
@@ -2,9 +2,7 @@ import { Buffer } from "node:buffer";
|
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import { LbbError } from "@littlebigbrain/client";
|
|
4
4
|
import { DEFAULT_DETAIL, HARD_OUTPUT_CHARS, MAX_QUERY_ROW_LIMIT, } from "./tool-contracts.js";
|
|
5
|
-
export const scoped = (client, graph
|
|
6
|
-
? client.withScope({ graph, branch })
|
|
7
|
-
: client;
|
|
5
|
+
export const scoped = (client, graph) => graph !== undefined ? client.withScope({ graph }) : client;
|
|
8
6
|
export function normalizeDetail(detail) {
|
|
9
7
|
return detail === "standard" || detail === "full" ? detail : DEFAULT_DETAIL;
|
|
10
8
|
}
|
|
@@ -50,9 +48,6 @@ export function assertCursorScope(args, cursor) {
|
|
|
50
48
|
if (args.graph !== undefined && args.graph !== cursor.graph) {
|
|
51
49
|
throw new Error("cursor graph does not match the supplied graph argument");
|
|
52
50
|
}
|
|
53
|
-
if (args.branch !== undefined && args.branch !== cursor.branch) {
|
|
54
|
-
throw new Error("cursor branch does not match the supplied branch argument");
|
|
55
|
-
}
|
|
56
51
|
}
|
|
57
52
|
export function rowPageFrom(value) {
|
|
58
53
|
if (!value || typeof value !== "object")
|
|
@@ -190,7 +185,7 @@ export function normalizeLbbIris(query) {
|
|
|
190
185
|
export function contentHashKey(scope, payload) {
|
|
191
186
|
const digest = createHash("sha256")
|
|
192
187
|
.update(stableJson({
|
|
193
|
-
scope: { graph: scope.graph ?? null
|
|
188
|
+
scope: { graph: scope.graph ?? null },
|
|
194
189
|
payload,
|
|
195
190
|
}))
|
|
196
191
|
.digest("hex");
|
|
@@ -440,60 +435,38 @@ export function errorResult(error) {
|
|
|
440
435
|
};
|
|
441
436
|
}
|
|
442
437
|
/**
|
|
443
|
-
* A graph-scope 404 surfaces as a raw object-storage key
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
438
|
+
* A graph-scope 404 surfaces as a raw object-storage key ending in
|
|
439
|
+
* `heads/current.json`, which only means something if you already know the
|
|
440
|
+
* graph's real name. Rewrite it into an actionable message: name the graph this
|
|
441
|
+
* request targeted and — via the tenant-scoped `GET /v1/graphs`, which resolves
|
|
442
|
+
* even when the scoped graph is absent — list the graphs that do exist and tell
|
|
443
|
+
* the caller to pass `graph=`. Every other error passes through untouched,
|
|
444
|
+
* including a head 404 on a graph the listing still reports.
|
|
450
445
|
*/
|
|
451
446
|
export async function enrichError(client, error) {
|
|
452
447
|
if (!(error instanceof LbbError) || error.status !== 404)
|
|
453
448
|
return error;
|
|
454
|
-
const match = /graphs\/([
|
|
449
|
+
const match = /graphs\/([^/\s]+)\/(?:[^/\s]+\/)*heads\/current\.json/.exec(error.message);
|
|
455
450
|
if (!match)
|
|
456
451
|
return error;
|
|
457
|
-
const [, graph
|
|
458
|
-
let
|
|
452
|
+
const [, graph] = match;
|
|
453
|
+
let names = [];
|
|
459
454
|
try {
|
|
460
455
|
const listed = (await client.listGraphs());
|
|
461
|
-
|
|
462
|
-
? [
|
|
463
|
-
{
|
|
464
|
-
graph_id: g.graph_id,
|
|
465
|
-
branches: Array.isArray(g.branches)
|
|
466
|
-
? g.branches
|
|
467
|
-
: undefined,
|
|
468
|
-
},
|
|
469
|
-
]
|
|
470
|
-
: []);
|
|
456
|
+
names = (listed.data ?? []).flatMap((g) => typeof g.graph_id === "string" ? [g.graph_id] : []);
|
|
471
457
|
}
|
|
472
458
|
catch {
|
|
473
459
|
// Listing failed too (auth, transport); fall back to the generic-but-actionable hint.
|
|
474
460
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
"Pass an existing branch as the `branch` argument.";
|
|
485
|
-
}
|
|
486
|
-
else {
|
|
487
|
-
const names = graphs.map((g) => g.graph_id);
|
|
488
|
-
const list = names.length > 0
|
|
489
|
-
? ` Available graphs in this tenant: ${names.slice(0, 50).join(", ")}.`
|
|
490
|
-
: "";
|
|
491
|
-
const example = names.length > 0 ? ` (e.g. graph="${names[0]}")` : "";
|
|
492
|
-
message =
|
|
493
|
-
`graph "${graph}" was not found in this tenant — this request targeted graph "${graph}", branch "${branch}" ` +
|
|
494
|
-
`(either you passed it or it is the connection default).${list} ` +
|
|
495
|
-
`Pass an existing graph as the \`graph\` argument${example}.`;
|
|
496
|
-
}
|
|
461
|
+
if (names.includes(graph))
|
|
462
|
+
return error;
|
|
463
|
+
const list = names.length > 0
|
|
464
|
+
? ` Available graphs in this tenant: ${names.slice(0, 50).join(", ")}.`
|
|
465
|
+
: "";
|
|
466
|
+
const example = names.length > 0 ? ` (e.g. graph="${names[0]}")` : "";
|
|
467
|
+
const message = `graph "${graph}" was not found in this tenant — this request targeted graph "${graph}" ` +
|
|
468
|
+
`(either you passed it or it is the connection default).${list} ` +
|
|
469
|
+
`Pass an existing graph as the \`graph\` argument${example}.`;
|
|
497
470
|
return new LbbError(error.status, error.body, {
|
|
498
471
|
type: error.type,
|
|
499
472
|
code: error.code,
|
|
@@ -683,8 +656,8 @@ export async function guide(scopedClient) {
|
|
|
683
656
|
relations,
|
|
684
657
|
capability: {
|
|
685
658
|
search_feedback: "When a result set is useful or clearly wrong, write relevance labels with lbb_commit mode=search_feedback. Use grade 3 for ideal/good results, grade 1 for partially relevant results, and grade 0 for bad results. Include the original query, search_id when present, target identity, rank, score, and an optional split train/eval/unspecified. These labels are stored in __lbb_feedback/main and later exported as qrels-style training/eval data; they are not customer facts.",
|
|
686
|
-
inspect: "Use lbb_inspect for ontology, schema metadata, the published conformance report, metadata,
|
|
687
|
-
ontology_decorations: "lbb_inspect action=ontology returns a decoration_status catalog: each ontology decoration is enforced (the engine acts on it — state_reducer, value_type, super_types, properties, supernode_policy; cardinality, which GET /v1/ontology/conformance audits as sh:maxCount; and inverse_name/symmetric, which SPARQL resolves as relation aliases — an inverse name is queryable directly (lowered to ^forward, no stored inverse triple) and a symmetric relation matches both directions), advisory (transitive, temporal_semantics, required), or reserved (stored but unwired — default_weight, resolvable, alias/embedding_fields). You can also always reverse any relation in SPARQL by flipping the triple pattern or using ^forward. Each relation_def also carries edge_count — the number of current edges of that relation in this
|
|
659
|
+
inspect: "Use lbb_inspect for ontology, schema metadata, the published conformance report, metadata, entities, and this guide. Use lbb_query with SPARQL property paths for exact path queries.",
|
|
660
|
+
ontology_decorations: "lbb_inspect action=ontology returns a decoration_status catalog: each ontology decoration is enforced (the engine acts on it — state_reducer, value_type, super_types, properties, supernode_policy; cardinality, which GET /v1/ontology/conformance audits as sh:maxCount; and inverse_name/symmetric, which SPARQL resolves as relation aliases — an inverse name is queryable directly (lowered to ^forward, no stored inverse triple) and a symmetric relation matches both directions), advisory (transitive, temporal_semantics, required), or reserved (stored but unwired — default_weight, resolvable, alias/embedding_fields). You can also always reverse any relation in SPARQL by flipping the triple pattern or using ^forward. Each relation_def also carries edge_count — the number of current edges of that relation in this graph's snapshot — so you can tell at a glance which declared relations are actually populated (edge_count 0 = declared but unused) without a separate summary call.",
|
|
688
661
|
search: "Use lbb_query mode=search to find instances by meaning. It covers every searchable class; filter narrows it by class and by relationship, and the graph checks every hit. To plan a search: (1) lbb_embeddings action=list gives the searchable classes, the facts each text is made from, and the graph's model. (2) lbb_query mode=sparql shows the relationships of a class on a sample: PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT ?p (COUNT(DISTINCT ?s) AS ?n) (SAMPLE(?l) AS ?example) WHERE { { SELECT ?s WHERE { ?s a <CLASS> } LIMIT 500 } ?s ?p ?o . FILTER(isIRI(?o) && ?p != rdf:type) OPTIONAL { ?o rdfs:label ?l } } GROUP BY ?p ORDER BY DESC(?n); write ?o ?p ?s for the links into the class, and SELECT ?c WHERE { ?c rdfs:subClassOf* <CLASS> } (same prefixes) for its subclasses. (3) lbb_query mode=search with filter [{class}, {via, to}] and explain=true returns the plan: the resolved relationship and entities, the allowed count, and the mode, with no model call. Check it, then run the search without explain. A name in to resolves against labels (a small typo too); an unknown relationship or name answers with the options.",
|
|
689
662
|
query: "Use lbb_query for structured SPARQL-subset bodies, SPARQL text, and canned analysis. SPARQL is the only query surface. A mode=structured body is { patterns: [{ subject, predicate, object }], filters?, group_by?, group_keys?, aggregates?, having? }; a pattern `predicate` is a relation name and is case-insensitive. mode=structured GROUP BY is not limited to entity identity: group_keys can key on a typed scalar property or calendar bucket. In SPARQL text, relations are <https://littlebigbrain.com/r/NAME> and types <https://littlebigbrain.com/class/NAME>. Each query pins one published watermark.",
|
|
690
663
|
write: "Use lbb_commit for fact writes and relevance feedback; omitted idempotency keys are content-derived so retries dedupe. Set typed scalar attributes via entity_properties once the field is registered (add it on a live graph with lbb_configure evolve_ontology add_property). For feedback, use mode=search_feedback rather than fact triplets.",
|
package/dist/tools.js
CHANGED
|
@@ -7,7 +7,7 @@ import { analyze, assertCursorScope, contentHashKey, decodeQueryCursor, effectiv
|
|
|
7
7
|
export function registerLbbTools(server, client, options = {}) {
|
|
8
8
|
registerRdfTool(server, client);
|
|
9
9
|
server.registerTool("lbb_inspect", {
|
|
10
|
-
description: "Read graph context and exact graph facts. Actions: guide, graphs, publication, ontology, ontology_conformance, schema, ontology_search, metadata, entity
|
|
10
|
+
description: "Read graph context and exact graph facts. Actions: guide, graphs, publication, ontology, ontology_conformance, schema, ontology_search, metadata, entity. graphs works before bootstrap; publication reports whether writes are queryable. ontology and schema return complete entries with page_size, section and cursor; follow next until absent. schema reads active native ontology/SHACL metadata without running validation. Query asserted RDF/OWL axioms separately with lbb_query. ontology_conformance serves the durable report referenced by the pinned published root. entity returns one node's attributes and current relationships from the RDF read. For a node's past values, run SPARQL with as_of_commit_seq through lbb_query. Use lbb_query with SPARQL property paths for precise path selection.",
|
|
11
11
|
inputSchema: inspectWireSchema,
|
|
12
12
|
annotations: READ_ONLY,
|
|
13
13
|
}, (rawArgs) => {
|
|
@@ -21,7 +21,7 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
21
21
|
.catch(async (error) => errorResult(await enrichError(client, error)));
|
|
22
22
|
}
|
|
23
23
|
return run(client, `lbb_inspect.${args.action}`, args.detail, () => {
|
|
24
|
-
const target = scoped(client, args.graph
|
|
24
|
+
const target = scoped(client, args.graph);
|
|
25
25
|
switch (args.action) {
|
|
26
26
|
case "guide":
|
|
27
27
|
return guide(target);
|
|
@@ -51,46 +51,6 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
51
51
|
asOf: args.as_of,
|
|
52
52
|
asOfCommitSeq: args.as_of_commit_seq,
|
|
53
53
|
});
|
|
54
|
-
case "state":
|
|
55
|
-
return target.currentState({
|
|
56
|
-
entity: {
|
|
57
|
-
entity_type: args.entity_type,
|
|
58
|
-
name: args.name,
|
|
59
|
-
},
|
|
60
|
-
relations: args.relation ? [args.relation] : null,
|
|
61
|
-
as_of_valid_time: args.as_of ?? null,
|
|
62
|
-
as_of_commit_seq: args.as_of_commit_seq ?? null,
|
|
63
|
-
});
|
|
64
|
-
case "history":
|
|
65
|
-
return target.history({
|
|
66
|
-
source: {
|
|
67
|
-
entity_type: args.entity_type,
|
|
68
|
-
name: args.name,
|
|
69
|
-
},
|
|
70
|
-
relation: args.relation ?? null,
|
|
71
|
-
});
|
|
72
|
-
case "why":
|
|
73
|
-
return target.why({
|
|
74
|
-
source: {
|
|
75
|
-
entity_type: args.source_type,
|
|
76
|
-
name: args.source_name,
|
|
77
|
-
},
|
|
78
|
-
relation: args.relation,
|
|
79
|
-
target: {
|
|
80
|
-
entity_type: args.target_type,
|
|
81
|
-
name: args.target_name,
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
case "transitions":
|
|
85
|
-
return target.transitions({
|
|
86
|
-
entity: {
|
|
87
|
-
entity_type: args.entity_type,
|
|
88
|
-
name: args.name,
|
|
89
|
-
},
|
|
90
|
-
relation: args.relation,
|
|
91
|
-
as_of_valid_time: args.as_of ?? null,
|
|
92
|
-
as_of_commit_seq: args.as_of_commit_seq ?? null,
|
|
93
|
-
});
|
|
94
54
|
}
|
|
95
55
|
});
|
|
96
56
|
});
|
|
@@ -110,7 +70,7 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
110
70
|
if (cursor && cursor.mode !== args.mode) {
|
|
111
71
|
throw new Error(`cursor is for ${cursor.mode}, not ${args.mode}`);
|
|
112
72
|
}
|
|
113
|
-
assertCursorScope({ graph: args.graph
|
|
73
|
+
assertCursorScope({ graph: args.graph }, cursor);
|
|
114
74
|
if (cursor &&
|
|
115
75
|
args.row_limit !== undefined &&
|
|
116
76
|
args.row_limit !== cursor.row_limit) {
|
|
@@ -119,9 +79,8 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
119
79
|
const detail = normalizeDetail(args.detail ?? cursor?.detail);
|
|
120
80
|
const rowLimit = effectiveRowLimit(detail, args.row_limit ?? cursor?.row_limit);
|
|
121
81
|
const graph = cursor?.graph ?? args.graph;
|
|
122
|
-
const branch = cursor?.branch ?? args.branch;
|
|
123
82
|
const offset = cursor?.offset ?? 0;
|
|
124
|
-
const target = scoped(client, graph
|
|
83
|
+
const target = scoped(client, graph);
|
|
125
84
|
const timing = queryTiming(options, {
|
|
126
85
|
mode: args.mode,
|
|
127
86
|
continuation: cursor !== undefined,
|
|
@@ -230,7 +189,6 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
230
189
|
v: 1,
|
|
231
190
|
mode: "structured",
|
|
232
191
|
graph,
|
|
233
|
-
branch,
|
|
234
192
|
detail,
|
|
235
193
|
row_limit: rowLimit,
|
|
236
194
|
body,
|
|
@@ -284,7 +242,6 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
284
242
|
v: 1,
|
|
285
243
|
mode: "sparql",
|
|
286
244
|
graph,
|
|
287
|
-
branch,
|
|
288
245
|
detail,
|
|
289
246
|
row_limit: rowLimit,
|
|
290
247
|
query,
|
|
@@ -305,7 +262,7 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
305
262
|
if (args.mode === "search") {
|
|
306
263
|
const searchArgs = args;
|
|
307
264
|
return run(client, "lbb_query.search", undefined, async () => {
|
|
308
|
-
const target = scoped(client, searchArgs.graph
|
|
265
|
+
const target = scoped(client, searchArgs.graph);
|
|
309
266
|
return target.embeddings.search({
|
|
310
267
|
embedding: searchArgs.embedding,
|
|
311
268
|
text: searchArgs.text,
|
|
@@ -319,7 +276,7 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
319
276
|
});
|
|
320
277
|
}
|
|
321
278
|
return run(client, `lbb_query.${args.mode}`, args.detail, async () => {
|
|
322
|
-
const target = scoped(client, args.graph
|
|
279
|
+
const target = scoped(client, args.graph);
|
|
323
280
|
return analyze(target, {
|
|
324
281
|
metric: args.metric,
|
|
325
282
|
chart: args.chart,
|
|
@@ -333,13 +290,7 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
333
290
|
server.registerTool("lbb_models", {
|
|
334
291
|
description: "Read model-training inputs or compare retrieval configurations over one pinned published snapshot. shadow_eval takes the API ShadowEvalRequest body; dataset actions return bounded training examples at an optional signal split.",
|
|
335
292
|
inputSchema: {
|
|
336
|
-
action: z.enum([
|
|
337
|
-
"shadow_eval",
|
|
338
|
-
"planner_dataset",
|
|
339
|
-
"planner_preference_dataset",
|
|
340
|
-
"suggest_dataset",
|
|
341
|
-
"extractor_dataset",
|
|
342
|
-
]),
|
|
293
|
+
action: z.enum(["shadow_eval", "suggest_dataset", "extractor_dataset"]),
|
|
343
294
|
body: jsonObjectSchema.optional(),
|
|
344
295
|
limit: z.number().int().positive().optional(),
|
|
345
296
|
split_seq: z.number().int().nonnegative().optional(),
|
|
@@ -347,20 +298,13 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
347
298
|
...graphScope,
|
|
348
299
|
},
|
|
349
300
|
annotations: READ_ONLY,
|
|
350
|
-
}, ({ action, body, limit, split_seq, detail, graph
|
|
351
|
-
const target = scoped(client, graph
|
|
301
|
+
}, ({ action, body, limit, split_seq, detail, graph }) => run(client, `lbb_models.${action}`, detail, () => {
|
|
302
|
+
const target = scoped(client, graph);
|
|
352
303
|
switch (action) {
|
|
353
304
|
case "shadow_eval":
|
|
354
305
|
if (!body)
|
|
355
306
|
throw new Error("shadow_eval requires body");
|
|
356
307
|
return target.shadowEval(body);
|
|
357
|
-
case "planner_dataset":
|
|
358
|
-
return target.plannerDataset({ limit, splitSeq: split_seq });
|
|
359
|
-
case "planner_preference_dataset":
|
|
360
|
-
return target.plannerPreferenceDataset({
|
|
361
|
-
limit,
|
|
362
|
-
splitSeq: split_seq,
|
|
363
|
-
});
|
|
364
308
|
case "suggest_dataset":
|
|
365
309
|
return target.suggestDataset({ limit, splitSeq: split_seq });
|
|
366
310
|
case "extractor_dataset":
|
|
@@ -416,7 +360,7 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
416
360
|
},
|
|
417
361
|
annotations: READ_ONLY,
|
|
418
362
|
}, (args) => run(client, `lbb_embeddings.${args.action}`, args.detail, () => {
|
|
419
|
-
const target = scoped(client, args.graph
|
|
363
|
+
const target = scoped(client, args.graph);
|
|
420
364
|
switch (args.action) {
|
|
421
365
|
case "list":
|
|
422
366
|
return target.embeddings.list();
|
|
@@ -446,7 +390,7 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
446
390
|
},
|
|
447
391
|
annotations: MUTATING,
|
|
448
392
|
}, (args) => run(client, `lbb_embeddings_manage.${args.action}`, args.detail, () => {
|
|
449
|
-
const target = scoped(client, args.graph
|
|
393
|
+
const target = scoped(client, args.graph);
|
|
450
394
|
switch (args.action) {
|
|
451
395
|
case "declare":
|
|
452
396
|
return target.embeddings.declare(recipeOf(args));
|
|
@@ -472,11 +416,11 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
472
416
|
...graphScope,
|
|
473
417
|
},
|
|
474
418
|
annotations: DESTRUCTIVE,
|
|
475
|
-
}, ({ name, confirm, detail, graph
|
|
419
|
+
}, ({ name, confirm, detail, graph }) => run(client, "lbb_embeddings_delete", detail, () => {
|
|
476
420
|
if (confirm !== name) {
|
|
477
421
|
throw new Error("confirm must repeat the embedding name");
|
|
478
422
|
}
|
|
479
|
-
return scoped(client, graph
|
|
423
|
+
return scoped(client, graph).embeddings.delete(name);
|
|
480
424
|
}));
|
|
481
425
|
server.registerTool("lbb_evals", {
|
|
482
426
|
description: "Managed evals: the thumbs up / thumbs down of the graph, per result. A query run with `request` (lbb_query) records a trace with one item per result (hit or row); trace reads it back with the item ids. label marks one result (item + valid) or several (items) relevant or not; the labels become the golden's ground truth. golden freezes a query (every result it returns now is relevant). run replays every golden at the current commit: pass when every relevant result is back and no wrong one is; new results open a review trace. judge lets the platform's judge model (the hosted frontier model) label unlabeled results. summary, traces, goldens, results, and settings read state.",
|
|
@@ -562,8 +506,8 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
562
506
|
...graphScope,
|
|
563
507
|
},
|
|
564
508
|
annotations: MUTATING,
|
|
565
|
-
}, ({ action, trace_id, item, valid, items, by, note, sparql, surface, embedding, top_k, request, golden_id, limit, unlabeled, consistency, detail, graph,
|
|
566
|
-
const target = scoped(client, graph
|
|
509
|
+
}, ({ action, trace_id, item, valid, items, by, note, sparql, surface, embedding, top_k, request, golden_id, limit, unlabeled, consistency, detail, graph, }) => run(client, `lbb_evals.${action}`, detail, () => {
|
|
510
|
+
const target = scoped(client, graph);
|
|
567
511
|
switch (action) {
|
|
568
512
|
case "summary":
|
|
569
513
|
return target.evals.summary();
|
|
@@ -684,7 +628,7 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
684
628
|
...graphScope,
|
|
685
629
|
},
|
|
686
630
|
annotations: IDEMPOTENT_WRITE,
|
|
687
|
-
}, ({ idempotency_key, mode, triplets, entity_embeddings, entity_properties, search_feedback, dry_run, observed_at, edge_idempotency, retract_edges, retract_entities, graph,
|
|
631
|
+
}, ({ idempotency_key, mode, triplets, entity_embeddings, entity_properties, search_feedback, dry_run, observed_at, edge_idempotency, retract_edges, retract_entities, graph, }) => run(client, "lbb_commit", "standard", () => {
|
|
688
632
|
const commitMode = mode ??
|
|
689
633
|
(search_feedback
|
|
690
634
|
? "search_feedback"
|
|
@@ -700,8 +644,8 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
700
644
|
throw new Error("lbb_commit mode=retract requires retract_edges or retract_entities");
|
|
701
645
|
}
|
|
702
646
|
const key = idempotency_key ??
|
|
703
|
-
contentHashKey({ graph
|
|
704
|
-
return scoped(client, graph
|
|
647
|
+
contentHashKey({ graph }, { mode: "retract", edges, entities });
|
|
648
|
+
return scoped(client, graph).retract({ edges, entities }, {
|
|
705
649
|
idempotencyKey: key,
|
|
706
650
|
});
|
|
707
651
|
}
|
|
@@ -709,8 +653,8 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
709
653
|
if (!search_feedback)
|
|
710
654
|
throw new Error("lbb_commit mode=search_feedback requires search_feedback");
|
|
711
655
|
const key = idempotency_key ??
|
|
712
|
-
contentHashKey({ graph
|
|
713
|
-
return scoped(client, graph
|
|
656
|
+
contentHashKey({ graph }, { mode: "search_feedback", search_feedback });
|
|
657
|
+
return scoped(client, graph).searchFeedback(search_feedback, { idempotencyKey: key });
|
|
714
658
|
}
|
|
715
659
|
if (search_feedback) {
|
|
716
660
|
throw new Error("lbb_commit facts mode cannot include search_feedback");
|
|
@@ -727,10 +671,10 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
727
671
|
payload.entity_properties.length === 0) {
|
|
728
672
|
throw new Error("lbb_commit requires at least one triplet, entity embedding, or entity property");
|
|
729
673
|
}
|
|
730
|
-
const key = idempotency_key ?? contentHashKey({ graph
|
|
674
|
+
const key = idempotency_key ?? contentHashKey({ graph }, payload);
|
|
731
675
|
if (dry_run)
|
|
732
|
-
return scoped(client, graph
|
|
733
|
-
return scoped(client, graph
|
|
676
|
+
return scoped(client, graph).commitDryRun(payload);
|
|
677
|
+
return scoped(client, graph).commit(payload, {
|
|
734
678
|
idempotencyKey: key,
|
|
735
679
|
});
|
|
736
680
|
}));
|
|
@@ -745,9 +689,7 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
745
689
|
const args = parsed.data;
|
|
746
690
|
return run(client, `lbb_configure.${args.action}`, "standard", () => {
|
|
747
691
|
if (args.action === "define_ontology") {
|
|
748
|
-
return client
|
|
749
|
-
.withScope({ graph: args.graph, branch: args.branch })
|
|
750
|
-
.ontologyDefine(ontologyDefineBody({
|
|
692
|
+
return client.withScope({ graph: args.graph }).ontologyDefine(ontologyDefineBody({
|
|
751
693
|
entity_types: args.entity_types,
|
|
752
694
|
relations: args.relations,
|
|
753
695
|
source: args.source,
|
|
@@ -757,7 +699,7 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
757
699
|
}));
|
|
758
700
|
}
|
|
759
701
|
if (args.action === "evolve_ontology") {
|
|
760
|
-
return scoped(client, args.graph
|
|
702
|
+
return scoped(client, args.graph).ontology.evolve({
|
|
761
703
|
ops: args.ops,
|
|
762
704
|
allow_data_conflicts: args.allow_data_conflicts ?? false,
|
|
763
705
|
}, { dryRun: args.dry_run });
|
|
@@ -765,7 +707,7 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
765
707
|
if (args.shapes === undefined) {
|
|
766
708
|
throw new Error("publish_schema requires a SHACL shapes source; use define_ontology or evolve_ontology for native metadata changes");
|
|
767
709
|
}
|
|
768
|
-
return scoped(client, args.graph
|
|
710
|
+
return scoped(client, args.graph).schema.publish({
|
|
769
711
|
ontology: args.ontology,
|
|
770
712
|
shapes: args.shapes,
|
|
771
713
|
desired_mode: args.desired_mode,
|
|
@@ -773,85 +715,4 @@ export function registerLbbTools(server, client, options = {}) {
|
|
|
773
715
|
}, { dryRun: args.dry_run });
|
|
774
716
|
});
|
|
775
717
|
});
|
|
776
|
-
server.registerTool("lbb_branch", {
|
|
777
|
-
description: "Branch lifecycle. Actions: create (fork a new branch off from_branch — the tool's `branch` argument names the NEW branch) and merge (validate-then-merge: replay from_branch's post-fork commits onto the scoped target branch — its fork parent — as ONE commit with event ids preserved; SHACL-validates the would-be merged state first and refuses with the report on violations; a fact superseded on the target after the fork wins over the branch's version, reported as a supersedure_race conflict; delete_source consumes the merged branch).",
|
|
778
|
-
inputSchema: {
|
|
779
|
-
action: z
|
|
780
|
-
.enum(["create", "merge"])
|
|
781
|
-
.describe("create = fork a new branch; merge = replay a child branch onto its fork parent"),
|
|
782
|
-
from_branch: z
|
|
783
|
-
.string()
|
|
784
|
-
.describe("create: the branch to fork from; merge: the child branch whose commits are replayed"),
|
|
785
|
-
validate: z
|
|
786
|
-
.boolean()
|
|
787
|
-
.optional()
|
|
788
|
-
.describe("merge only: refuse on SHACL violations of the would-be merged state (default true)"),
|
|
789
|
-
delete_source: z
|
|
790
|
-
.boolean()
|
|
791
|
-
.optional()
|
|
792
|
-
.describe("merge only: delete every object under the merged branch after success"),
|
|
793
|
-
...graphScope,
|
|
794
|
-
},
|
|
795
|
-
annotations: MUTATING,
|
|
796
|
-
}, ({ action, from_branch, validate, delete_source, graph, branch }) => run(client, `lbb_branch.${action}`, "standard", () => {
|
|
797
|
-
const target = scoped(client, graph, branch);
|
|
798
|
-
if (action === "create")
|
|
799
|
-
return target.createBranch({ from_branch });
|
|
800
|
-
return target.mergeBranch({
|
|
801
|
-
from_branch,
|
|
802
|
-
validate: validate ?? true,
|
|
803
|
-
delete_source: delete_source ?? false,
|
|
804
|
-
});
|
|
805
|
-
}));
|
|
806
|
-
server.registerTool("lbb_observe", {
|
|
807
|
-
description: "Remember a conversation: store the turns verbatim as an EPISODE evidence entity, then anchor + gate the supplied facts on an observe branch (LLM extraction cannot poison the main graph). Facts with both endpoints already in the graph are anchored; unanchored facts need confidence >= 0.8 to mint new entities, else they come back needs_review. auto_merge merges the branch onto the scoped branch when SHACL validation is clean (the validate-then-merge). Server flag-gated (--enable-observe). This build takes caller-extracted facts (each with a structured triplet); bare statements come back needs_review.",
|
|
808
|
-
inputSchema: {
|
|
809
|
-
session_id: z
|
|
810
|
-
.string()
|
|
811
|
-
.describe("Caller's conversation id (drives the default observe branch name)"),
|
|
812
|
-
turns: z
|
|
813
|
-
.array(z.object({
|
|
814
|
-
role: z.string().describe("user | assistant | tool"),
|
|
815
|
-
content: z.string(),
|
|
816
|
-
name: z.string().optional(),
|
|
817
|
-
ts: z.string().optional().describe("RFC 3339 timestamp"),
|
|
818
|
-
}))
|
|
819
|
-
.min(1)
|
|
820
|
-
.describe("The conversation slice to remember (stored verbatim)"),
|
|
821
|
-
source: z
|
|
822
|
-
.string()
|
|
823
|
-
.optional()
|
|
824
|
-
.describe("Source label, e.g. support-bot"),
|
|
825
|
-
facts: z
|
|
826
|
-
.array(z.object({
|
|
827
|
-
fact: z.string().describe("Natural-language statement"),
|
|
828
|
-
confidence: z.number().optional().describe("0..1 (default 0.9)"),
|
|
829
|
-
triplet: jsonObjectSchema
|
|
830
|
-
.optional()
|
|
831
|
-
.describe("Structured form {source:{type,name}, relation, target:{type,name}} — required for the fact to commit"),
|
|
832
|
-
}))
|
|
833
|
-
.optional()
|
|
834
|
-
.describe("Caller-extracted candidate facts; omit with extract:false to store the episode only"),
|
|
835
|
-
extract: z
|
|
836
|
-
.boolean()
|
|
837
|
-
.optional()
|
|
838
|
-
.describe("false = store the episode only (default true)"),
|
|
839
|
-
observe_branch: z
|
|
840
|
-
.string()
|
|
841
|
-
.optional()
|
|
842
|
-
.describe("Branch for the facts (default observe-<hash12(session_id)>)"),
|
|
843
|
-
auto_merge: z
|
|
844
|
-
.boolean()
|
|
845
|
-
.optional()
|
|
846
|
-
.describe("Merge onto the scoped branch when validation is clean"),
|
|
847
|
-
...graphScope,
|
|
848
|
-
},
|
|
849
|
-
annotations: MUTATING,
|
|
850
|
-
}, ({ session_id, turns, source, facts, extract, observe_branch, auto_merge, graph, branch, }) => run(client, "lbb_observe", "standard", () => scoped(client, graph, branch).observe({
|
|
851
|
-
episode: { turns, session_id, source },
|
|
852
|
-
extract: extract ?? true,
|
|
853
|
-
extraction: { byo_completion: (facts ?? []) },
|
|
854
|
-
branch: observe_branch,
|
|
855
|
-
auto_merge: auto_merge ?? false,
|
|
856
|
-
})));
|
|
857
718
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@littlebigbrain/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "MCP server for little big brain: search, graph queries, and data import",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"test:coverage": "npm run clean:test && tsc -p tsconfig.test.json && node --test --experimental-test-coverage --test-coverage-include=test-dist/*.js --test-coverage-exclude=test-dist/*.test.js --test-coverage-exclude=test-dist/stdio.js --test-coverage-exclude=test-dist/test-support.js --test-coverage-lines=90 --test-coverage-branches=70 --test-coverage-functions=85 \"test-dist/**/*.test.js\""
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@littlebigbrain/client": "^0.
|
|
55
|
+
"@littlebigbrain/client": "^0.15.0",
|
|
56
56
|
"@modelcontextprotocol/sdk": "^1",
|
|
57
57
|
"zod": "^3"
|
|
58
58
|
},
|