@productbrain/mcp 0.0.1-beta.8928 → 0.0.1-beta.8933
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.
|
@@ -1277,31 +1277,16 @@ function formatRubricVerdictSection(verdict) {
|
|
|
1277
1277
|
|
|
1278
1278
|
// src/lib/captureSinglePreviewOutput.ts
|
|
1279
1279
|
import { z as z3 } from "zod/v3";
|
|
1280
|
-
var groundingRelatedEntrySchema = z3.object({
|
|
1281
|
-
entryId: z3.string(),
|
|
1282
|
-
name: z3.string(),
|
|
1283
|
-
collectionSlug: z3.string(),
|
|
1284
|
-
overlapRatio: z3.number(),
|
|
1285
|
-
reasoning: z3.string()
|
|
1286
|
-
});
|
|
1287
1280
|
var groundingDuplicateEntrySchema = z3.object({
|
|
1288
1281
|
entryId: z3.string(),
|
|
1289
1282
|
name: z3.string(),
|
|
1290
1283
|
collectionSlug: z3.string(),
|
|
1291
|
-
matchType: z3.enum(["related", "possible_duplicate"]),
|
|
1292
1284
|
overlapRatio: z3.number()
|
|
1293
1285
|
});
|
|
1294
|
-
var groundingGovernanceEntrySchema = z3.object({
|
|
1295
|
-
entryId: z3.string(),
|
|
1296
|
-
name: z3.string(),
|
|
1297
|
-
collectionSlug: z3.string()
|
|
1298
|
-
});
|
|
1299
1286
|
var groundingReportSchema = z3.object({
|
|
1300
1287
|
// TASK-156: null preserves uncertainty for unavailable checks or an older server response.
|
|
1301
1288
|
scanTruncated: z3.boolean().nullable(),
|
|
1302
|
-
|
|
1303
|
-
duplicates: z3.array(groundingDuplicateEntrySchema),
|
|
1304
|
-
governance: z3.array(groundingGovernanceEntrySchema)
|
|
1289
|
+
duplicates: z3.array(groundingDuplicateEntrySchema)
|
|
1305
1290
|
});
|
|
1306
1291
|
var taskAlignmentSchema = z3.record(z3.unknown());
|
|
1307
1292
|
var captureSinglePreviewOutputSchema = z3.object({
|
|
@@ -1385,10 +1370,6 @@ var captureSchema = z4.object({
|
|
|
1385
1370
|
sourceExcerpt: z4.string().optional().describe("Verbatim excerpt from the source that backs this entry's claims. Stored as top-level entry field, not in data."),
|
|
1386
1371
|
// WP-316 S3: Preview gate — dry-run mode. Returns what would happen, no DB writes.
|
|
1387
1372
|
preview: z4.boolean().optional().describe("If true, validates the capture without writing. Returns what would happen. Default false."),
|
|
1388
|
-
// WP-318 S2: Pre-write grounding — run link suggestion before creating entry.
|
|
1389
|
-
suggestOnly: z4.boolean().optional().describe("If true, runs pre-write grounding (chain.capture) and returns a groundingReport WITHOUT creating any entry. Use to preview graph participation before accepting. Default false."),
|
|
1390
|
-
// WP-318 S2: Format for groundingReport in response.
|
|
1391
|
-
format: z4.enum(["agent", "human"]).optional().describe("Response format for grounding data. 'agent' (default): full JSON groundingReport. 'human': compressed summary string appended to the capture summary."),
|
|
1392
1373
|
// WP-513: explicit role to create AS OWNER of (rung 2 only). WP-753 O1b (DEC-1715):
|
|
1393
1374
|
// ownerTeamEntryId is deleted — the server takes the team you hold the role in (root first, else the shallowest),
|
|
1394
1375
|
// and an unnamed create resolves a default owner itself instead of landing ownerless.
|
|
@@ -1683,6 +1664,7 @@ var captureOutputSchema = z4.union([
|
|
|
1683
1664
|
captureClassifierOnlyOutputSchema
|
|
1684
1665
|
]);
|
|
1685
1666
|
var CAPTURE_ACTIONS = ["capture"];
|
|
1667
|
+
var SUGGEST_ONLY_REMOVED = "suggestOnly was removed: call capture with preview: true to check a capture without writing.";
|
|
1686
1668
|
var captureCompoundSchema = z4.object({
|
|
1687
1669
|
action: z4.enum(CAPTURE_ACTIONS).optional().default("capture").describe("Create a single knowledge entry."),
|
|
1688
1670
|
collection: z4.string().max(200).optional().describe("Collection slug, e.g. 'tensions', 'business-rules', 'glossary', 'decisions'. Optional \u2014 classifier auto-routes when omitted."),
|
|
@@ -1700,8 +1682,8 @@ var captureCompoundSchema = z4.object({
|
|
|
1700
1682
|
sourceRef: z4.string().max(2e3).optional().describe("URI or path of the source document backing this entry."),
|
|
1701
1683
|
sourceExcerpt: z4.string().max(SOURCE_EXCERPT_MAX_CHARS).optional().describe("Verbatim excerpt from the source backing this entry's claims."),
|
|
1702
1684
|
preview: z4.boolean().optional().describe("If true, validates without writing."),
|
|
1703
|
-
suggestOnly: z4.
|
|
1704
|
-
|
|
1685
|
+
suggestOnly: z4.never({ invalid_type_error: SUGGEST_ONLY_REMOVED }).optional().describe(SUGGEST_ONLY_REMOVED),
|
|
1686
|
+
// TASK-608: refused, never stripped into a write.
|
|
1705
1687
|
// WP-513: explicit role to create AS OWNER of (rung 2 only). WP-753 O1b: ownerTeamEntryId
|
|
1706
1688
|
// deleted — team is the one you hold the role in (root first, else the shallowest).
|
|
1707
1689
|
ownerRoleEntryId: z4.string().max(200).optional().describe("Owning role (rung-2); you must hold it; its team is the one you hold it in (root first, else the shallowest).")
|
|
@@ -1712,7 +1694,7 @@ var captureActionUnion = z4.discriminatedUnion("action", [
|
|
|
1712
1694
|
]);
|
|
1713
1695
|
var CAPTURE_ACTION_SPECS = {
|
|
1714
1696
|
capture: {
|
|
1715
|
-
params: ["collection", "name", "description", "context", "entryId", "canonicalKey", "data", "why", "links", "sourceRef", "sourceExcerpt", "preview"
|
|
1697
|
+
params: ["collection", "name", "description", "context", "entryId", "canonicalKey", "data", "why", "links", "sourceRef", "sourceExcerpt", "preview"],
|
|
1716
1698
|
description: "name and description are required."
|
|
1717
1699
|
}
|
|
1718
1700
|
};
|
|
@@ -1746,7 +1728,7 @@ All other collections get an ENT-{random} ID and sensible defaults.
|
|
|
1746
1728
|
})
|
|
1747
1729
|
);
|
|
1748
1730
|
}
|
|
1749
|
-
async function handleCapture(server, { collection, name, description, context, entryId, canonicalKey, data: userData, why, links, sourceRef, sourceExcerpt, preview,
|
|
1731
|
+
async function handleCapture(server, { collection, name, description, context, entryId, canonicalKey, data: userData, why, links, sourceRef, sourceExcerpt, preview, ownerRoleEntryId }) {
|
|
1750
1732
|
requireWriteAccess();
|
|
1751
1733
|
const timingStart = Date.now();
|
|
1752
1734
|
const wsCtx = await getWorkspaceContext();
|
|
@@ -1824,73 +1806,12 @@ async function handleCapture(server, { collection, name, description, context, e
|
|
|
1824
1806
|
const groundingRaw = await Promise.race([groundingPromise, new Promise((r) => setTimeout(() => r(null), 500))]);
|
|
1825
1807
|
const groundingElapsedMs = Date.now() - groundingStart;
|
|
1826
1808
|
const groundingEntry = groundingRaw ?? null;
|
|
1827
|
-
const groundingRelated = groundingEntry?.kind === "create_and_link" ? groundingEntry.candidates.map((c) => ({ entryId: c.entryId, name: c.name, collectionSlug: c.collectionSlug, overlapRatio: c.score, reasoning: `${Math.round(c.score * 100)}% match` })) : [];
|
|
1828
|
-
const groundingDuplicates = groundingEntry?.kind === "ask" ? groundingEntry.candidates.map((c) => ({ entryId: c.entryId, name: c.name, collectionSlug: c.collectionSlug, matchType: "related", overlapRatio: c.score })) : groundingEntry?.kind === "version" ? [{ entryId: groundingEntry.entryId, name: groundingEntry.name, collectionSlug: groundingEntry.collectionSlug, matchType: "possible_duplicate", overlapRatio: groundingEntry.score }] : [];
|
|
1829
|
-
const groundingGovernance = [];
|
|
1830
1809
|
const groundingReport = {
|
|
1831
1810
|
// null preserves uncertainty for unavailable checks or an older server response.
|
|
1832
1811
|
scanTruncated: typeof groundingEntry?.scanTruncated === "boolean" ? groundingEntry.scanTruncated : null,
|
|
1833
|
-
|
|
1834
|
-
entryId: r.entryId,
|
|
1835
|
-
name: r.name,
|
|
1836
|
-
collectionSlug: r.collectionSlug,
|
|
1837
|
-
overlapRatio: r.overlapRatio,
|
|
1838
|
-
reasoning: r.reasoning
|
|
1839
|
-
})),
|
|
1840
|
-
duplicates: groundingDuplicates.map((d) => ({
|
|
1841
|
-
entryId: d.entryId,
|
|
1842
|
-
name: d.name,
|
|
1843
|
-
collectionSlug: d.collectionSlug,
|
|
1844
|
-
matchType: d.matchType,
|
|
1845
|
-
overlapRatio: d.overlapRatio
|
|
1846
|
-
})),
|
|
1847
|
-
governance: groundingGovernance
|
|
1812
|
+
duplicates: groundingEntry?.kind === "ask" ? groundingEntry.candidates.map((c) => ({ entryId: c.entryId, name: c.name, collectionSlug: c.collectionSlug, overlapRatio: c.score })) : []
|
|
1848
1813
|
};
|
|
1849
1814
|
const groundingCaveat = !groundingEntry ? "Grounding could not be completed; duplicate presence is unknown. Review existing entries before creating another." : groundingReport.scanTruncated !== false ? "Grounding covered a bounded sample; completeness is unverified and additional matching entries may exist. Review existing entries before creating another." : "";
|
|
1850
|
-
if (suggestOnly) {
|
|
1851
|
-
const hasSuggestions = groundingReport.related.length > 0 || groundingReport.duplicates.length > 0;
|
|
1852
|
-
const summaryText = hasSuggestions ? `Grounding preview for "${name}": ${groundingReport.related.length} related, ${groundingReport.duplicates.length} possible duplicates. No entry created.` : groundingEntry ? `Grounding preview for "${name}": no similar entries found in this check. No entry created.` : `Grounding preview for "${name}": duplicate check unavailable. No entry created.`;
|
|
1853
|
-
return {
|
|
1854
|
-
content: [{
|
|
1855
|
-
type: "text",
|
|
1856
|
-
text: `# Grounding Preview \u2014 No Entry Created
|
|
1857
|
-
|
|
1858
|
-
${summaryText}
|
|
1859
|
-
|
|
1860
|
-
` + (groundingCaveat ? `${groundingCaveat}
|
|
1861
|
-
|
|
1862
|
-
` : "") + (groundingReport.related.length > 0 ? `## Related entries
|
|
1863
|
-
${groundingReport.related.map((r) => `- **${r.entryId}** ${r.name} [${r.collectionSlug}] \u2014 ${r.reasoning}`).join("\n")}
|
|
1864
|
-
|
|
1865
|
-
` : "") + (groundingReport.duplicates.length > 0 ? `## Possible duplicates
|
|
1866
|
-
${groundingReport.duplicates.map((d) => `- **${d.entryId}** ${d.name} [${d.collectionSlug}] (${d.matchType}, overlap: ${d.overlapRatio})`).join("\n")}
|
|
1867
|
-
|
|
1868
|
-
` : "") + // "## Governance entries to review" ternary removed (item 5d, dead — see line ~1051).
|
|
1869
|
-
`_Call \`capture\` without \`suggestOnly\` to proceed with entry creation._`
|
|
1870
|
-
}],
|
|
1871
|
-
structuredContent: {
|
|
1872
|
-
...success(
|
|
1873
|
-
summaryText,
|
|
1874
|
-
{ groundingReport, outcome: "suggest_only" },
|
|
1875
|
-
// Fix 3 sibling (TEN-2918 follow-up): thread the caller's full original payload —
|
|
1876
|
-
// see lib/captureForRealAction.ts's doc comment.
|
|
1877
|
-
buildCaptureForRealNextAction({
|
|
1878
|
-
collection: resolvedCollection,
|
|
1879
|
-
name,
|
|
1880
|
-
description,
|
|
1881
|
-
context,
|
|
1882
|
-
entryId,
|
|
1883
|
-
canonicalKey,
|
|
1884
|
-
data: userData,
|
|
1885
|
-
links,
|
|
1886
|
-
sourceRef,
|
|
1887
|
-
sourceExcerpt,
|
|
1888
|
-
ownerRoleEntryId
|
|
1889
|
-
})
|
|
1890
|
-
)
|
|
1891
|
-
}
|
|
1892
|
-
};
|
|
1893
|
-
}
|
|
1894
1815
|
if (groundingEntry?.kind === "version") return captureVersionOrPreview(preview ?? false, { groundingEntry, name, description, data: userData, sourceRef, sourceExcerpt, links, groundingElapsedMs });
|
|
1895
1816
|
const built = buildDataFromFieldsOrRefuse(col.fields ?? [], profile.descriptionField, description, resolvedCollection);
|
|
1896
1817
|
if ("refusal" in built) return built.refusal;
|
|
@@ -1989,13 +1910,10 @@ ${groundingReport.duplicates.map((d) => `- **${d.entryId}** ${d.name} [${d.colle
|
|
|
1989
1910
|
});
|
|
1990
1911
|
if (result2 && isPreviewCreateEntryResult(result2)) {
|
|
1991
1912
|
const preflight = await resolvePreviewPreflight(result2, links);
|
|
1992
|
-
const
|
|
1993
|
-
const groundingSummary =
|
|
1913
|
+
const dupCount = groundingReport.duplicates.length;
|
|
1914
|
+
const groundingSummary = dupCount > 0 ? `
|
|
1994
1915
|
|
|
1995
|
-
**
|
|
1996
|
-
groundingReport.duplicates.length > 0 && `${groundingReport.duplicates.length} possible duplicate${groundingReport.duplicates.length > 1 ? "s" : ""}`,
|
|
1997
|
-
groundingReport.related.length > 0 && `${groundingReport.related.length} related entr${groundingReport.related.length > 1 ? "ies" : "y"}`
|
|
1998
|
-
].filter(Boolean).join(", ")}.` : "";
|
|
1916
|
+
**Possible duplicates:** ${dupCount}.` : "";
|
|
1999
1917
|
const wouldBlock = result2.wouldBlock === true;
|
|
2000
1918
|
const headline = wouldBlock ? `Preview: would be BLOCKED \u2014 "${name}" [${resolvedCollection}]` : `Preview: would capture "${name}" [${resolvedCollection}]`;
|
|
2001
1919
|
const previewEnvelope = success(
|
|
@@ -2092,11 +2010,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`entries action=up
|
|
|
2092
2010
|
void kernelMutation("chain.recordGroundingOutcome", {
|
|
2093
2011
|
surface: "mcp",
|
|
2094
2012
|
promptShown: groundingEntry?.kind === "ask",
|
|
2095
|
-
highestRatio: Math.max(
|
|
2096
|
-
...groundingReport.duplicates.map((d) => d.overlapRatio),
|
|
2097
|
-
...groundingReport.related.map((r) => r.overlapRatio),
|
|
2098
|
-
0
|
|
2099
|
-
),
|
|
2013
|
+
highestRatio: Math.max(...groundingReport.duplicates.map((d) => d.overlapRatio), 0),
|
|
2100
2014
|
hadGovernance: false,
|
|
2101
2015
|
grounding_ms: groundingElapsedMs
|
|
2102
2016
|
}).catch(() => void 0);
|
|
@@ -2267,17 +2181,6 @@ Use \`entries action=get\` to inspect the existing entry, or \`entries action=up
|
|
|
2267
2181
|
lines.push(`Next: \`entries action=commit entryId="${finalEntryId}"\`.`);
|
|
2268
2182
|
}
|
|
2269
2183
|
if (groundingCaveat) lines.push("", groundingCaveat);
|
|
2270
|
-
if (format === "human") {
|
|
2271
|
-
const hasDuplicates = groundingReport.duplicates.length > 0;
|
|
2272
|
-
const hasRelated = groundingReport.related.length > 0;
|
|
2273
|
-
if (hasDuplicates || hasRelated) {
|
|
2274
|
-
lines.push("");
|
|
2275
|
-
const parts = [];
|
|
2276
|
-
if (hasDuplicates) parts.push(`${groundingReport.duplicates.length} possible duplicate${groundingReport.duplicates.length > 1 ? "s" : ""}`);
|
|
2277
|
-
if (hasRelated) parts.push(`${groundingReport.related.length} related entr${groundingReport.related.length > 1 ? "ies" : "y"}`);
|
|
2278
|
-
lines.push(`_Grounding: ${parts.join(", ")}. Review and link if relevant._`);
|
|
2279
|
-
}
|
|
2280
|
-
}
|
|
2281
2184
|
if (formativeHints.length > 0) {
|
|
2282
2185
|
lines.push("");
|
|
2283
2186
|
lines.push("## Quality Hints (advisory)");
|
|
@@ -2416,7 +2319,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`entries action=up
|
|
|
2416
2319
|
qualityHints: formativeHints,
|
|
2417
2320
|
// WP-745 TASK-160 (PR #901 review): the machine-readable projection — was reaching the human text only.
|
|
2418
2321
|
...spineFloor && { spineFloor },
|
|
2419
|
-
// WP-318 S2:
|
|
2322
|
+
// WP-318 S2: the possible-duplicate report — always included (empty when no ask match)
|
|
2420
2323
|
groundingReport
|
|
2421
2324
|
},
|
|
2422
2325
|
next
|
|
@@ -13681,4 +13584,4 @@ export {
|
|
|
13681
13584
|
createProductBrainServer,
|
|
13682
13585
|
initFeatureFlags
|
|
13683
13586
|
};
|
|
13684
|
-
//# sourceMappingURL=chunk-
|
|
13587
|
+
//# sourceMappingURL=chunk-C6EYMV77.js.map
|