@productbrain/mcp 0.0.1-beta.8754 → 0.0.1-beta.8762
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.
|
@@ -1171,23 +1171,29 @@ function verdictQualityPhrase(result2) {
|
|
|
1171
1171
|
if (!v || criteria.length === 0) {
|
|
1172
1172
|
return "Quality: not evaluated (no rubric for this type).";
|
|
1173
1173
|
}
|
|
1174
|
-
const
|
|
1175
|
-
const
|
|
1176
|
-
|
|
1174
|
+
const gating = criteria.filter((c) => c.gating !== false);
|
|
1175
|
+
const total = gating.length;
|
|
1176
|
+
const passed = gating.filter((c) => c.passed).length;
|
|
1177
|
+
return v.passed ? `Quality: all ${total} gating criteria pass.` : `Quality: ${passed}/${total} gating criteria pass \u2014 see the coaching above.`;
|
|
1178
|
+
}
|
|
1179
|
+
function hintLines(criteria) {
|
|
1180
|
+
const hints = (criteria ?? []).filter((c) => c.gating === false && !c.passed);
|
|
1181
|
+
return hints.length === 0 ? [] : ["", ...hints.map((c) => `hint (does not block): ${c.id} \u2014 ${c.hint}`)];
|
|
1177
1182
|
}
|
|
1178
1183
|
function formatRubricCoaching(result2) {
|
|
1179
1184
|
const { verdict, rogerMartin } = result2;
|
|
1180
1185
|
if (!verdict || verdict.criteria.length === 0) return "";
|
|
1181
1186
|
const lines = ["## Semantic Quality"];
|
|
1182
|
-
const
|
|
1183
|
-
const
|
|
1187
|
+
const gating = (verdict.criteria ?? []).filter((c) => c.gating !== false);
|
|
1188
|
+
const failed = gating.filter((c) => !c.passed);
|
|
1189
|
+
const total = gating.length;
|
|
1184
1190
|
const passedCount = total - failed.length;
|
|
1185
1191
|
if (verdict.passed) {
|
|
1186
|
-
lines.push(`All ${total}
|
|
1192
|
+
lines.push(`All ${total} gating criteria pass for \`${verdict.canonicalKey}\` (${verdict.tier} tier).`);
|
|
1187
1193
|
} else {
|
|
1188
|
-
lines.push(`${passedCount}/${total} criteria pass for \`${verdict.canonicalKey}\` (${verdict.tier} tier)`);
|
|
1194
|
+
lines.push(`${passedCount}/${total} gating criteria pass for \`${verdict.canonicalKey}\` (${verdict.tier} tier)`);
|
|
1189
1195
|
lines.push("");
|
|
1190
|
-
for (const c of
|
|
1196
|
+
for (const c of gating) {
|
|
1191
1197
|
const icon = c.passed ? "[x]" : "[ ]";
|
|
1192
1198
|
const extra = c.passed ? "" : ` \u2014 ${c.hint}`;
|
|
1193
1199
|
lines.push(`${icon} ${c.id}${extra}`);
|
|
@@ -1198,6 +1204,7 @@ function formatRubricCoaching(result2) {
|
|
|
1198
1204
|
lines.push(`_Question to consider:_ ${verdict.weakest.questionTemplate}`);
|
|
1199
1205
|
}
|
|
1200
1206
|
}
|
|
1207
|
+
lines.push(...hintLines(verdict.criteria));
|
|
1201
1208
|
if (rogerMartin) {
|
|
1202
1209
|
lines.push("");
|
|
1203
1210
|
lines.push("### Roger Martin Test");
|
|
@@ -1215,17 +1222,18 @@ function formatRubricCoaching(result2) {
|
|
|
1215
1222
|
function formatRubricVerdictSection(verdict) {
|
|
1216
1223
|
if (!verdict || !verdict.criteria || verdict.criteria.length === 0) return "";
|
|
1217
1224
|
const lines = ["## Semantic Quality"];
|
|
1218
|
-
const
|
|
1219
|
-
const
|
|
1225
|
+
const gating = verdict.criteria.filter((c) => c.gating !== false);
|
|
1226
|
+
const failed = gating.filter((c) => !c.passed);
|
|
1227
|
+
const total = gating.length;
|
|
1220
1228
|
const passedCount = total - failed.length;
|
|
1221
1229
|
const durationSuffix = verdict.llmDurationMs ? ` in ${(verdict.llmDurationMs / 1e3).toFixed(1)}s` : "";
|
|
1222
1230
|
const statusNote = verdict.llmStatus === "pending" ? " \u2014 LLM evaluation in progress..." : verdict.llmStatus === "failed" ? ` \u2014 LLM evaluation failed${verdict.llmError ? `: ${verdict.llmError}` : ""}, showing heuristic results` : verdict.source === "llm" && durationSuffix ? ` \u2014 evaluated${durationSuffix}` : "";
|
|
1223
1231
|
if (failed.length === 0) {
|
|
1224
|
-
lines.push(`All ${total}
|
|
1232
|
+
lines.push(`All ${total} gating criteria pass for \`${verdict.canonicalKey}\` (${verdict.tier} tier, ${verdict.source} evaluation).${statusNote}`);
|
|
1225
1233
|
} else {
|
|
1226
|
-
lines.push(`${passedCount}/${total} criteria pass for \`${verdict.canonicalKey}\` (${verdict.tier} tier, ${verdict.source} evaluation)${statusNote}`);
|
|
1234
|
+
lines.push(`${passedCount}/${total} gating criteria pass for \`${verdict.canonicalKey}\` (${verdict.tier} tier, ${verdict.source} evaluation)${statusNote}`);
|
|
1227
1235
|
lines.push("");
|
|
1228
|
-
for (const c of
|
|
1236
|
+
for (const c of gating) {
|
|
1229
1237
|
const icon = c.passed ? "[x]" : "[ ]";
|
|
1230
1238
|
const extra = c.passed ? "" : ` \u2014 ${c.hint}`;
|
|
1231
1239
|
lines.push(`${icon} ${c.id}${extra}`);
|
|
@@ -1235,6 +1243,7 @@ function formatRubricVerdictSection(verdict) {
|
|
|
1235
1243
|
lines.push(`**Top improvement:** ${verdict.weakest.hint}`);
|
|
1236
1244
|
}
|
|
1237
1245
|
}
|
|
1246
|
+
lines.push(...hintLines(verdict.criteria));
|
|
1238
1247
|
if (verdict.rogerMartin) {
|
|
1239
1248
|
const rm = verdict.rogerMartin;
|
|
1240
1249
|
lines.push("");
|
|
@@ -2302,7 +2311,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`entries action=up
|
|
|
2302
2311
|
try {
|
|
2303
2312
|
const wsForTracking = await getWorkspaceContext();
|
|
2304
2313
|
const v = verdictResult.verdict;
|
|
2305
|
-
const failedCount = (v.criteria ?? []).filter((c) => !c.passed).length;
|
|
2314
|
+
const failedCount = (v.criteria ?? []).filter((c) => !c.passed && c.gating !== false).length;
|
|
2306
2315
|
trackQualityVerdict(wsForTracking.workspaceId, {
|
|
2307
2316
|
entry_id: finalEntryId,
|
|
2308
2317
|
entry_type: v.canonicalKey ?? resolvedCollection,
|
|
@@ -2310,7 +2319,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`entries action=up
|
|
|
2310
2319
|
context: "capture",
|
|
2311
2320
|
passed: v.passed,
|
|
2312
2321
|
source: verdictResult.source ?? "heuristic",
|
|
2313
|
-
criteria_total: v.criteria
|
|
2322
|
+
criteria_total: (v.criteria ?? []).filter((c) => c.gating !== false).length,
|
|
2314
2323
|
criteria_failed: failedCount,
|
|
2315
2324
|
llm_scheduled: v.tier !== "passive",
|
|
2316
2325
|
methodology_version: v.methodologyVersion
|
|
@@ -2999,7 +3008,7 @@ No DB writes \u2014 call without \`preview:true\` to accept for real.` }],
|
|
|
2999
3008
|
if (coachingResult?.verdict) {
|
|
3000
3009
|
try {
|
|
3001
3010
|
const v = coachingResult.verdict;
|
|
3002
|
-
const failedCount = (v.criteria ?? []).filter((c) => !c.passed).length;
|
|
3011
|
+
const failedCount = (v.criteria ?? []).filter((c) => !c.passed && c.gating !== false).length;
|
|
3003
3012
|
trackQualityVerdict(wsCtx.workspaceId, {
|
|
3004
3013
|
entry_id: entryId,
|
|
3005
3014
|
entry_type: v.canonicalKey ?? entry.canonicalKey ?? "",
|
|
@@ -3007,7 +3016,7 @@ No DB writes \u2014 call without \`preview:true\` to accept for real.` }],
|
|
|
3007
3016
|
context: "commit",
|
|
3008
3017
|
passed: v.passed,
|
|
3009
3018
|
source: coachingResult.source ?? "heuristic",
|
|
3010
|
-
criteria_total: v.criteria
|
|
3019
|
+
criteria_total: (v.criteria ?? []).filter((c) => c.gating !== false).length,
|
|
3011
3020
|
criteria_failed: failedCount,
|
|
3012
3021
|
llm_scheduled: v.tier !== "passive",
|
|
3013
3022
|
methodology_version: v.methodologyVersion
|
|
@@ -10531,7 +10540,9 @@ var qualityCheckOutputSchema = z21.object({
|
|
|
10531
10540
|
criteria: z21.array(z21.object({
|
|
10532
10541
|
id: z21.string(),
|
|
10533
10542
|
passed: z21.boolean(),
|
|
10534
|
-
hint: z21.string().optional()
|
|
10543
|
+
hint: z21.string().optional(),
|
|
10544
|
+
/** TASK-588 / DEC-1908: false = a coaching hint; an unmet one never fails the verdict. */
|
|
10545
|
+
gating: z21.literal(false).optional()
|
|
10535
10546
|
}))
|
|
10536
10547
|
});
|
|
10537
10548
|
var qualityReevaluateOutputSchema = z21.object({
|
|
@@ -10636,9 +10647,10 @@ Entry \`${entryId}\` not found. Use \`search\` to find the right ID.`,
|
|
|
10636
10647
|
}
|
|
10637
10648
|
const criteria = verdict.criteria ?? [];
|
|
10638
10649
|
const lines = [`# Quality Check: ${entryId}`, ""];
|
|
10650
|
+
const staleWhy = res.staleReason === "methodology_changed_since_judged" ? "the rubric changed since it was judged" : "the entry was edited since it was judged";
|
|
10639
10651
|
if (res.stale) {
|
|
10640
10652
|
lines.push(
|
|
10641
|
-
`> STALE \u2014 this verdict
|
|
10653
|
+
`> STALE \u2014 this verdict for \`${entryId}\` no longer counts: ${staleWhy}. Run \`quality action=re-evaluate entryId="${entryId}"\` for a current verdict.`,
|
|
10642
10654
|
""
|
|
10643
10655
|
);
|
|
10644
10656
|
}
|
|
@@ -10660,10 +10672,11 @@ Entry \`${entryId}\` not found. Use \`search\` to find the right ID.`,
|
|
|
10660
10672
|
});
|
|
10661
10673
|
} catch {
|
|
10662
10674
|
}
|
|
10663
|
-
const
|
|
10675
|
+
const gatingCriteria = criteria.filter((c) => c.gating !== false);
|
|
10676
|
+
const passedCount = gatingCriteria.filter((c) => c.passed).length;
|
|
10664
10677
|
return successResult(
|
|
10665
10678
|
lines.join("\n"),
|
|
10666
|
-
`Quality check for ${entryId}: ${verdict.tier ?? "unknown"} tier, ${passedCount}/${
|
|
10679
|
+
`Quality check for ${entryId}: ${verdict.tier ?? "unknown"} tier, ${passedCount}/${gatingCriteria.length} gating criteria pass.` + (res.stale ? ` STALE \u2014 ${staleWhy}; re-evaluate for a current one.` : ""),
|
|
10667
10680
|
{
|
|
10668
10681
|
entryId,
|
|
10669
10682
|
entryFound: true,
|
|
@@ -10671,7 +10684,7 @@ Entry \`${entryId}\` not found. Use \`search\` to find the right ID.`,
|
|
|
10671
10684
|
stale: res.stale ?? false,
|
|
10672
10685
|
tier: verdict.tier,
|
|
10673
10686
|
passed: verdict.passed,
|
|
10674
|
-
criteria: criteria.map((c) => ({ id: c.id, passed: c.passed, hint: c.hint }))
|
|
10687
|
+
criteria: criteria.map((c) => ({ id: c.id, passed: c.passed, hint: c.hint, ...c.gating === false ? { gating: false } : {} }))
|
|
10675
10688
|
},
|
|
10676
10689
|
[
|
|
10677
10690
|
{ tool: "relations", description: "Suggest connections", parameters: { action: "suggest", entryId } }
|
|
@@ -10710,14 +10723,15 @@ async function handleReEvaluate(entryId, context) {
|
|
|
10710
10723
|
context,
|
|
10711
10724
|
passed: result2.verdict.passed ?? false,
|
|
10712
10725
|
source: "heuristic",
|
|
10713
|
-
|
|
10714
|
-
|
|
10726
|
+
// TASK-588 / DEC-1908: totals and fails count gating criteria; a gating:false one is a hint.
|
|
10727
|
+
criteria_total: result2.verdict.criteria?.filter((c) => c.gating !== false).length ?? 0,
|
|
10728
|
+
criteria_failed: result2.verdict.criteria?.filter((c) => !c.passed && c.gating !== false).length ?? 0,
|
|
10715
10729
|
llm_scheduled: llmScheduled,
|
|
10716
10730
|
methodology_version: result2.verdict.methodologyVersion
|
|
10717
10731
|
});
|
|
10718
10732
|
} catch {
|
|
10719
10733
|
}
|
|
10720
|
-
const criteria = result2.verdict.criteria ?? [];
|
|
10734
|
+
const criteria = (result2.verdict.criteria ?? []).filter((c) => c.gating !== false);
|
|
10721
10735
|
const reEvalScore = criteria.filter((c) => c.passed).length;
|
|
10722
10736
|
const reEvalMaxScore = criteria.length;
|
|
10723
10737
|
return {
|
|
@@ -14143,4 +14157,4 @@ export {
|
|
|
14143
14157
|
createProductBrainServer,
|
|
14144
14158
|
initFeatureFlags
|
|
14145
14159
|
};
|
|
14146
|
-
//# sourceMappingURL=chunk-
|
|
14160
|
+
//# sourceMappingURL=chunk-ZY4ORNVP.js.map
|