@promptev/context-engine 0.0.3 → 0.0.5
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 +65 -1
- package/dist/cli.js +732 -37
- package/dist/cli.js.map +1 -1
- package/dist/express.cjs +205 -21
- package/dist/express.cjs.map +1 -1
- package/dist/express.js +205 -21
- package/dist/express.js.map +1 -1
- package/dist/fastify.cjs +205 -21
- package/dist/fastify.cjs.map +1 -1
- package/dist/fastify.js +205 -21
- package/dist/fastify.js.map +1 -1
- package/dist/hono.cjs +205 -21
- package/dist/hono.cjs.map +1 -1
- package/dist/hono.js +205 -21
- package/dist/hono.js.map +1 -1
- package/dist/index.cjs +755 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +276 -3
- package/dist/index.d.ts +276 -3
- package/dist/index.js +749 -39
- package/dist/index.js.map +1 -1
- package/dist/{mcp-BKSmxayM.d.cts → mcp-uirRbluA.d.cts} +4 -0
- package/dist/{mcp-BKSmxayM.d.ts → mcp-uirRbluA.d.ts} +4 -0
- package/dist/mcp.cjs +50 -10
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.d.cts +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +50 -10
- package/dist/mcp.js.map +1 -1
- package/dist/skills/context-engine/SKILL.md +54 -1
- package/package.json +1 -1
- package/src/skills/context-engine/SKILL.md +54 -1
package/dist/mcp.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import 'node:http';
|
|
2
|
-
export { i as createMcpApp } from './mcp-
|
|
2
|
+
export { i as createMcpApp } from './mcp-uirRbluA.cjs';
|
package/dist/mcp.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import 'node:http';
|
|
2
|
-
export { i as createMcpApp } from './mcp-
|
|
2
|
+
export { i as createMcpApp } from './mcp-uirRbluA.js';
|
package/dist/mcp.js
CHANGED
|
@@ -407,7 +407,7 @@ var KNOWLEDGE_ACTIONS = [
|
|
|
407
407
|
"get_neighbors",
|
|
408
408
|
"community_summary"
|
|
409
409
|
];
|
|
410
|
-
var KNOWLEDGE_TOOL_DESCRIPTION = "The knowledge base \u2014 the ingested documents and data files (PDF, Word, Excel, CSV and the rest) \u2014 as ONE tool with actions. Nothing is searched for you: use it before answering anything that should come from those documents, and do not use it for general knowledge. Call action 'discover' FIRST when you do not already know what is there: it lists the documents
|
|
410
|
+
var KNOWLEDGE_TOOL_DESCRIPTION = "The knowledge base \u2014 the ingested documents and data files (PDF, Word, Excel, CSV and the rest) \u2014 as ONE tool with actions. Nothing is searched for you: use it before answering anything that should come from those documents, and do not use it for general knowledge. Call action 'discover' FIRST when you do not already know what is there: it lists the documents and says what is INSIDE each one \u2014 a spreadsheet's sheet names, column headers and row counts; a document's section titles and last page; a JSON file's top-level keys \u2014 plus the extracted field names grouped by document type with each field's data type and how many documents carry it, a census of the whole corpus, and which actions this deployment can run. Use those names verbatim: they are what compute, query_meta and get_chunks match on, so one discover is enough and you never have to go looking for a column, a section or a field name. A long list is shortened there, with the rest reported as a count and, when it is worth the trip, the exact call that returns it in full \u2014 discover again with document_ids set to that one document, which answers whole. When it is not worth the trip the payload says so and says what to do instead: a sheet with hundreds of columns is one to compute over, never one to read back. Then match the action to the task. 'search' finds passages by meaning or keywords \u2014 for questions answered by reading text. Looking up an identifier (an ID, code, SKU or invoice number) is the exception: search the BARE identifier alone, e.g. '2525', never the whole question. Those are CONTENT identifiers \u2014 written inside a document \u2014 and they belong in a query; a document_id is a system id (a uuid) that only discover, list or a search hit can give you, so never search a uuid as text and never hand an invoice number to get_doc. 'get_doc' reads one whole document by id, 'get_docs' reads several at once, and 'get_chunks' walks one long document in order a piece at a time when you need more of it than an excerpt; 'list' browses the documents without searching. 'map_reduce' asks the SAME question of every document in scope and answers once per document \u2014 for 'which contracts mention X', where search would return a handful of passages and miss the rest. 'query_meta' filters and aggregates documents by their structured fields (dates, amounts, categories) \u2014 usually the right action for a question about spreadsheet data. 'compute' runs code over the spreadsheets for any figure DERIVED from them \u2014 a total, average, count, ranking, margin or comparison across rows \u2014 AND for finding the exact row matching one id or value. In a large table, search cannot reliably locate an individual row; compute can. When the question is about how things are CONNECTED rather than what a document says \u2014 who works with whom, what belongs to what, what a change touches \u2014 use the graph actions: 'get_neighbors' for what is one step from one thing, 'traverse' for everything within a few steps of it, 'find_related' for connections of a kind across the corpus, and 'community_summary' for the themes the corpus groups into. They are available only where a graph was built; discover says so. Searching with mode='graph' ranks passages by those same connections instead of by wording alone, which finds a passage that never repeats your words. Rules that decide answers: search returns EXCERPTS, and rows of a spreadsheet are not arithmetic \u2014 never add up, average or rank rows yourself from what search returned, and never say a figure is not available before computing over the sheet that holds it. A listing that says has_more has MORE: send its next_cursor back as 'cursor' for the next page, and never conclude a document is absent from a first page that was truncated. Search again with different words before saying a document is missing. A result may carry a next_action (or next_page): it is the call to make next, already filled in \u2014 follow it rather than guessing the next step. Cite document names.";
|
|
411
411
|
var ACTION_PARAM_DESCRIPTION = "Match it to the task: reading questions -> search (a bare identifier for an ID or code); spreadsheet analysis, or the exact row for one id or value -> query_meta or compute; how things connect -> get_neighbors, traverse, find_related or community_summary; browse everything -> list; unsure what exists -> discover first.";
|
|
412
412
|
var ACTION_HELP = {
|
|
413
413
|
search: "passages by meaning or keywords; an ID, code or number as the BARE identifier",
|
|
@@ -430,7 +430,7 @@ var OFF = {
|
|
|
430
430
|
graph: "the graph actions are off: this deployment has no graph configured, so nothing has been linked up. Use search, get_doc or list instead."
|
|
431
431
|
};
|
|
432
432
|
var GRAPH_ACTIONS = ["traverse", "find_related", "get_neighbors", "community_summary"];
|
|
433
|
-
var DOCUMENT_ID_ACTIONS = ["search", "compute", "get_docs", "map_reduce"];
|
|
433
|
+
var DOCUMENT_ID_ACTIONS = ["search", "compute", "get_docs", "map_reduce", "discover", "list"];
|
|
434
434
|
var DEFAULT_GET_DOCS_CHARS = 2e5;
|
|
435
435
|
var INPUT_PROPERTIES = {
|
|
436
436
|
action: { type: "string", enum: [...KNOWLEDGE_ACTIONS], description: ACTION_PARAM_DESCRIPTION },
|
|
@@ -450,7 +450,7 @@ var INPUT_PROPERTIES = {
|
|
|
450
450
|
document_ids: {
|
|
451
451
|
type: "array",
|
|
452
452
|
items: { type: "string" },
|
|
453
|
-
description: "Narrows to these documents, using ids from discover, list or a search hit. It INTERSECTS with source_ids, so a document outside the sources you named returns nothing. (for search, compute)"
|
|
453
|
+
description: "Narrows to these documents, using ids from discover, list or a search hit. It INTERSECTS with source_ids, so a document outside the sources you named returns nothing. On discover it also asks for those documents' structure IN FULL, past the shortening a whole-page discover applies. (for search, compute, get_docs, map_reduce, discover, list)"
|
|
454
454
|
},
|
|
455
455
|
entity: {
|
|
456
456
|
type: "string",
|
|
@@ -566,11 +566,16 @@ function parseCursor(cursor) {
|
|
|
566
566
|
}
|
|
567
567
|
return parsed;
|
|
568
568
|
}
|
|
569
|
-
async function listPage(engine, sourceIds, principals, action, limit, cursor, ceiling, redaction) {
|
|
569
|
+
async function listPage(engine, sourceIds, principals, action, limit, cursor, documentIds, ceiling, redaction) {
|
|
570
570
|
const page = await engine.listDocuments({
|
|
571
571
|
// `!= null`, NOT truthiness: an EMPTY array means "nothing is in scope"
|
|
572
572
|
// and collapsing it to null would list the whole corpus.
|
|
573
573
|
sourceIds: sourceIds != null ? [...new Set(sourceIds)] : null,
|
|
574
|
+
// Already intersected with the host's ceiling by `narrowToCeiling`, and
|
|
575
|
+
// filtered in SQL rather than after the page is built — three named
|
|
576
|
+
// documents sitting on page four must come back as themselves, not as an
|
|
577
|
+
// empty page.
|
|
578
|
+
documentIds: documentIds != null ? [...new Set(documentIds)] : null,
|
|
574
579
|
principals,
|
|
575
580
|
cursor,
|
|
576
581
|
limit: Math.max(1, Math.min(limit, MAX_LIST_LIMIT)),
|
|
@@ -580,7 +585,9 @@ async function listPage(engine, sourceIds, principals, action, limit, cursor, ce
|
|
|
580
585
|
id: String(raw.id),
|
|
581
586
|
name: raw.name,
|
|
582
587
|
source_id: raw.sourceId ?? raw.source_id,
|
|
583
|
-
kind: documentKind(raw)
|
|
588
|
+
kind: documentKind(raw),
|
|
589
|
+
document_type: raw.documentType ?? raw.document_type ?? null,
|
|
590
|
+
mode: raw.mode ?? null
|
|
584
591
|
}));
|
|
585
592
|
if (ceiling.documentIds != null) {
|
|
586
593
|
const allowed = new Set(ceiling.documentIds);
|
|
@@ -633,30 +640,62 @@ async function callKnowledgeTool(engine, args) {
|
|
|
633
640
|
action,
|
|
634
641
|
args.limit ?? 50,
|
|
635
642
|
parseCursor(args.cursor),
|
|
643
|
+
documentIds,
|
|
636
644
|
ceiling,
|
|
637
645
|
args.redaction
|
|
638
646
|
);
|
|
639
647
|
if (action === "list") return { success: true, ...page };
|
|
640
|
-
const
|
|
648
|
+
const structures = await engine.documentStructure({
|
|
649
|
+
documentIds: page.documents.map((d) => d.id),
|
|
650
|
+
sourceIds,
|
|
651
|
+
principals,
|
|
652
|
+
// The cap is for the call that did NOT name its documents. A caller
|
|
653
|
+
// that asked about specific documents asked for all of them, and the
|
|
654
|
+
// truncated payload tells it to make exactly this call — so answering
|
|
655
|
+
// it truncated again would be a loop.
|
|
656
|
+
bounded: !requestedDocumentIds?.length,
|
|
657
|
+
redaction: args.redaction
|
|
658
|
+
});
|
|
659
|
+
for (const doc of page.documents) doc.structure = structures[doc.id] ?? {};
|
|
660
|
+
const hasSpreadsheet = page.documents.some((d) => d.kind === "spreadsheet");
|
|
661
|
+
const fieldsByType = await engine.fieldSummary({
|
|
662
|
+
sourceIds,
|
|
663
|
+
documentIds,
|
|
664
|
+
principals,
|
|
665
|
+
redaction: args.redaction
|
|
666
|
+
});
|
|
667
|
+
const census = await engine.documentTypes({
|
|
668
|
+
sourceIds,
|
|
669
|
+
documentIds,
|
|
670
|
+
principals,
|
|
671
|
+
redaction: args.redaction
|
|
672
|
+
});
|
|
641
673
|
const forAFact = { action: "search", query: "<bare identifier or key words>" };
|
|
642
674
|
const nextAction = {};
|
|
643
|
-
if (
|
|
675
|
+
if (hasSpreadsheet && available.compute) {
|
|
644
676
|
nextAction["for a figure from a spreadsheet"] = {
|
|
645
677
|
action: "compute",
|
|
646
|
-
query: "<what to compute, columns as named>"
|
|
678
|
+
query: "<what to compute, columns as named above>"
|
|
647
679
|
};
|
|
648
680
|
}
|
|
649
681
|
nextAction["for a clause or a fact"] = forAFact;
|
|
682
|
+
if (fieldsByType.length && available.query_meta) {
|
|
683
|
+
nextAction["for documents by a field value"] = {
|
|
684
|
+
action: "query_meta",
|
|
685
|
+
query: "<a question naming a field from fields_by_type>"
|
|
686
|
+
};
|
|
687
|
+
}
|
|
650
688
|
if (available.get_neighbors) {
|
|
651
689
|
nextAction["for how things connect"] = {
|
|
652
690
|
action: "get_neighbors",
|
|
653
691
|
entity: "<a name that appears in the documents>"
|
|
654
692
|
};
|
|
655
693
|
}
|
|
656
|
-
|
|
694
|
+
const discovered = {
|
|
657
695
|
success: true,
|
|
658
696
|
...page,
|
|
659
|
-
|
|
697
|
+
document_types: census,
|
|
698
|
+
fields_by_type: fieldsByType,
|
|
660
699
|
available_actions: Object.fromEntries(
|
|
661
700
|
Object.keys(ACTION_HELP).map((name) => [
|
|
662
701
|
name,
|
|
@@ -665,6 +704,7 @@ async function callKnowledgeTool(engine, args) {
|
|
|
665
704
|
),
|
|
666
705
|
next_action: nextAction
|
|
667
706
|
};
|
|
707
|
+
return discovered;
|
|
668
708
|
}
|
|
669
709
|
if (action === "search") {
|
|
670
710
|
if (!text) return { success: false, error: "search needs a query" };
|