@productbrain/mcp 0.0.1-beta.75 → 0.0.1-beta.77
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/dist/{chunk-ZJBP7BE4.js → chunk-YIVFK6VL.js} +163 -2197
- package/dist/chunk-YIVFK6VL.js.map +1 -0
- package/dist/{chunk-UEUFJX5P.js → chunk-ZY3ORYC3.js} +205 -110
- package/dist/chunk-ZY3ORYC3.js.map +1 -0
- package/dist/http.js +2 -2
- package/dist/index.js +2 -2
- package/dist/{smart-capture-2L44VU22.js → smart-capture-VFCEUDDW.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-UEUFJX5P.js.map +0 -1
- package/dist/chunk-ZJBP7BE4.js.map +0 -1
- /package/dist/{smart-capture-2L44VU22.js.map → smart-capture-VFCEUDDW.js.map} +0 -0
|
@@ -1227,6 +1227,19 @@ function withEnvelope(handler) {
|
|
|
1227
1227
|
};
|
|
1228
1228
|
}
|
|
1229
1229
|
|
|
1230
|
+
// src/lib/fieldTypes.ts
|
|
1231
|
+
var FIELD_TYPE_DEFAULTS = {
|
|
1232
|
+
"string": "",
|
|
1233
|
+
"text": "",
|
|
1234
|
+
"rich-text": "",
|
|
1235
|
+
"number": null,
|
|
1236
|
+
"boolean": false,
|
|
1237
|
+
"select": null,
|
|
1238
|
+
"multi-select": [],
|
|
1239
|
+
"array": [],
|
|
1240
|
+
"json": null
|
|
1241
|
+
};
|
|
1242
|
+
|
|
1230
1243
|
// src/tools/smart-capture-routing.ts
|
|
1231
1244
|
var STARTER_COLLECTIONS = CLASSIFIABLE_COLLECTIONS;
|
|
1232
1245
|
|
|
@@ -2123,7 +2136,17 @@ var captureSuccessOutputSchema = z2.object({
|
|
|
2123
2136
|
qualityScore: z2.number(),
|
|
2124
2137
|
qualityVerdict: z2.record(z2.unknown()).optional(),
|
|
2125
2138
|
classifier: captureClassifierSchema.optional(),
|
|
2126
|
-
studioUrl: z2.string().optional()
|
|
2139
|
+
studioUrl: z2.string().optional(),
|
|
2140
|
+
warnings: z2.array(z2.string()).optional(),
|
|
2141
|
+
normalization: z2.object({
|
|
2142
|
+
remapped: z2.record(z2.string()).optional(),
|
|
2143
|
+
rejected: z2.array(z2.string()).optional()
|
|
2144
|
+
}).optional(),
|
|
2145
|
+
expectedFields: z2.array(z2.object({
|
|
2146
|
+
key: z2.string(),
|
|
2147
|
+
type: z2.string(),
|
|
2148
|
+
required: z2.boolean().optional()
|
|
2149
|
+
})).optional()
|
|
2127
2150
|
}).strict();
|
|
2128
2151
|
var captureClassifierOnlyOutputSchema = z2.object({
|
|
2129
2152
|
classifier: captureClassifierSchema
|
|
@@ -2140,7 +2163,12 @@ var batchCaptureOutputSchema = z2.object({
|
|
|
2140
2163
|
status: z2.enum(["draft", "committed", "proposed"]),
|
|
2141
2164
|
classifiedBy: z2.enum(["llm", "heuristic", "explicit"]).optional(),
|
|
2142
2165
|
confidence: z2.number().optional(),
|
|
2143
|
-
confidenceTier: z2.enum(["high", "medium", "low"]).optional()
|
|
2166
|
+
confidenceTier: z2.enum(["high", "medium", "low"]).optional(),
|
|
2167
|
+
warnings: z2.array(z2.string()).optional(),
|
|
2168
|
+
normalization: z2.object({
|
|
2169
|
+
remapped: z2.record(z2.string()).optional(),
|
|
2170
|
+
rejected: z2.array(z2.string()).optional()
|
|
2171
|
+
}).optional()
|
|
2144
2172
|
})),
|
|
2145
2173
|
total: z2.number(),
|
|
2146
2174
|
failed: z2.number(),
|
|
@@ -2169,6 +2197,17 @@ var batchCaptureOutputSchema = z2.object({
|
|
|
2169
2197
|
function shouldAutoCommitCapture(autoCommit, governanceMode) {
|
|
2170
2198
|
return autoCommit === true || autoCommit === void 0 && governanceMode === "open";
|
|
2171
2199
|
}
|
|
2200
|
+
function buildDataFromFields(fields, descriptionField, descriptionValue) {
|
|
2201
|
+
const data = {};
|
|
2202
|
+
for (const field of fields) {
|
|
2203
|
+
if (field.key === descriptionField) {
|
|
2204
|
+
data[field.key] = descriptionValue;
|
|
2205
|
+
} else {
|
|
2206
|
+
data[field.key] = FIELD_TYPE_DEFAULTS[field.type] ?? null;
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
return data;
|
|
2210
|
+
}
|
|
2172
2211
|
function registerSmartCaptureTools(server) {
|
|
2173
2212
|
const captureTool = server.registerTool(
|
|
2174
2213
|
"capture",
|
|
@@ -2230,19 +2269,8 @@ Or use \`collections action=list\` to see available collections.`
|
|
|
2230
2269
|
)
|
|
2231
2270
|
};
|
|
2232
2271
|
}
|
|
2233
|
-
const data =
|
|
2272
|
+
const data = buildDataFromFields(col.fields ?? [], profile.descriptionField, description);
|
|
2234
2273
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
2235
|
-
for (const field of col.fields ?? []) {
|
|
2236
|
-
const key = field.key;
|
|
2237
|
-
if (key === profile.descriptionField) {
|
|
2238
|
-
data[key] = description;
|
|
2239
|
-
} else if (field.type === "array" || field.type === "multi-select") {
|
|
2240
|
-
data[key] = [];
|
|
2241
|
-
} else if (field.type === "select") {
|
|
2242
|
-
} else {
|
|
2243
|
-
data[key] = "";
|
|
2244
|
-
}
|
|
2245
|
-
}
|
|
2246
2274
|
for (const def of profile.defaults) {
|
|
2247
2275
|
if (def.value === "today") {
|
|
2248
2276
|
data[def.key] = today;
|
|
@@ -2287,10 +2315,43 @@ Or use \`collections action=list\` to see available collections.`
|
|
|
2287
2315
|
}
|
|
2288
2316
|
data.links = betLinks;
|
|
2289
2317
|
}
|
|
2318
|
+
const E2_LLM_REMAP_ENABLED = false;
|
|
2319
|
+
const payloadForPreview = E2_LLM_REMAP_ENABLED && userData && typeof userData === "object" ? { ...data } : null;
|
|
2320
|
+
if (payloadForPreview) {
|
|
2321
|
+
try {
|
|
2322
|
+
const preview = await mcpCall(
|
|
2323
|
+
"chain.normalizeEntryDataPreview",
|
|
2324
|
+
{ collectionSlug: resolvedCollection, data: payloadForPreview }
|
|
2325
|
+
);
|
|
2326
|
+
const rejected = (preview?.rejected ?? []).filter((k) => k !== "name");
|
|
2327
|
+
if (rejected.length > 0) {
|
|
2328
|
+
const llmResult = await mcpCall(
|
|
2329
|
+
"chain.normalizeEntryDataLLM",
|
|
2330
|
+
{
|
|
2331
|
+
collectionSlug: resolvedCollection,
|
|
2332
|
+
unknownKeys: rejected,
|
|
2333
|
+
data: payloadForPreview
|
|
2334
|
+
}
|
|
2335
|
+
);
|
|
2336
|
+
if (llmResult && Object.keys(llmResult.remapped).length > 0) {
|
|
2337
|
+
const fieldKeySet = new Set((col.fields ?? []).map((f) => f.key));
|
|
2338
|
+
for (const [oldKey, newKey] of Object.entries(llmResult.remapped)) {
|
|
2339
|
+
if (data[oldKey] !== void 0 && !fieldKeySet.has(oldKey)) {
|
|
2340
|
+
data[newKey] = data[oldKey];
|
|
2341
|
+
delete data[oldKey];
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
} catch {
|
|
2347
|
+
}
|
|
2348
|
+
}
|
|
2290
2349
|
const status = "draft";
|
|
2291
2350
|
const agentId = getAgentSessionId();
|
|
2292
2351
|
let finalEntryId;
|
|
2293
2352
|
let internalId;
|
|
2353
|
+
let entryWarnings = [];
|
|
2354
|
+
let normalizationMeta;
|
|
2294
2355
|
try {
|
|
2295
2356
|
const result = await mcpMutation("chain.createEntry", {
|
|
2296
2357
|
collectionSlug: resolvedCollection,
|
|
@@ -2304,6 +2365,8 @@ Or use \`collections action=list\` to see available collections.`
|
|
|
2304
2365
|
});
|
|
2305
2366
|
internalId = result.docId;
|
|
2306
2367
|
finalEntryId = result.entryId;
|
|
2368
|
+
entryWarnings = result.warnings ?? [];
|
|
2369
|
+
normalizationMeta = result.normalization;
|
|
2307
2370
|
resolveGapsForEntry(name, result.entryId);
|
|
2308
2371
|
} catch (error) {
|
|
2309
2372
|
const msg = error instanceof Error ? error.message : String(error);
|
|
@@ -2333,6 +2396,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2333
2396
|
const linksCreated = [];
|
|
2334
2397
|
const linksSuggested = [];
|
|
2335
2398
|
const userLinkResults = [];
|
|
2399
|
+
const pendingRelations = [];
|
|
2336
2400
|
const skipAutoDiscovery = links && links.length > 0;
|
|
2337
2401
|
const searchQuery = extractSearchTerms(name, description);
|
|
2338
2402
|
if (searchQuery && !skipAutoDiscovery) {
|
|
@@ -2351,63 +2415,95 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2351
2415
|
confidenceReason: conf.reason
|
|
2352
2416
|
};
|
|
2353
2417
|
}).sort((a, b) => b.confidence - a.confidence);
|
|
2418
|
+
let autoCount = 0;
|
|
2354
2419
|
for (const c of candidates) {
|
|
2355
|
-
if (
|
|
2420
|
+
if (autoCount >= MAX_AUTO_LINKS) break;
|
|
2356
2421
|
if (c.confidence < AUTO_LINK_CONFIDENCE_THRESHOLD) break;
|
|
2357
2422
|
if (!c.entryId || !finalEntryId) continue;
|
|
2358
2423
|
const { type: relationType, reason: relationReason } = inferRelationType(resolvedCollection, c.collSlug, profile);
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
});
|
|
2366
|
-
linksCreated.push({
|
|
2367
|
-
targetEntryId: c.entryId,
|
|
2424
|
+
pendingRelations.push({
|
|
2425
|
+
fromEntryId: finalEntryId,
|
|
2426
|
+
toEntryId: c.entryId,
|
|
2427
|
+
type: relationType,
|
|
2428
|
+
meta: {
|
|
2429
|
+
source: "auto",
|
|
2368
2430
|
targetName: c.name,
|
|
2369
2431
|
targetCollection: c.collSlug,
|
|
2370
|
-
relationType,
|
|
2371
2432
|
linkReason: `confidence ${c.confidence} (${c.confidenceReason}) + ${relationReason}`
|
|
2372
|
-
}
|
|
2373
|
-
}
|
|
2374
|
-
|
|
2433
|
+
}
|
|
2434
|
+
});
|
|
2435
|
+
autoCount++;
|
|
2375
2436
|
}
|
|
2376
|
-
const
|
|
2437
|
+
const autoTargetIds = new Set(pendingRelations.map((r) => r.toEntryId));
|
|
2377
2438
|
for (const c of candidates) {
|
|
2378
2439
|
if (linksSuggested.length >= MAX_SUGGESTIONS) break;
|
|
2379
|
-
if (
|
|
2440
|
+
if (autoTargetIds.has(c.entryId)) continue;
|
|
2380
2441
|
if (c.confidence < 10) continue;
|
|
2381
2442
|
const preview = extractPreview(c.data, 80);
|
|
2382
2443
|
const reason = c.confidence >= AUTO_LINK_CONFIDENCE_THRESHOLD ? "high relevance (already linked)" : `"${c.name.toLowerCase().split(/\s+/).filter((w) => `${name} ${description}`.toLowerCase().includes(w) && w.length > 3).slice(0, 2).join('", "')}" appears in content`;
|
|
2383
|
-
linksSuggested.push({
|
|
2384
|
-
entryId: c.entryId,
|
|
2385
|
-
name: c.name,
|
|
2386
|
-
collection: c.collSlug,
|
|
2387
|
-
reason,
|
|
2388
|
-
preview
|
|
2389
|
-
});
|
|
2444
|
+
linksSuggested.push({ entryId: c.entryId, name: c.name, collection: c.collSlug, reason, preview });
|
|
2390
2445
|
}
|
|
2391
2446
|
}
|
|
2392
2447
|
if (links && links.length > 0 && finalEntryId) {
|
|
2393
2448
|
for (const link of links) {
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2449
|
+
pendingRelations.push({
|
|
2450
|
+
fromEntryId: finalEntryId,
|
|
2451
|
+
toEntryId: link.to,
|
|
2452
|
+
type: link.type,
|
|
2453
|
+
meta: { source: "user", targetName: link.to, targetCollection: "unknown" }
|
|
2454
|
+
});
|
|
2455
|
+
}
|
|
2456
|
+
}
|
|
2457
|
+
const resolvedCK = canonicalKey;
|
|
2458
|
+
const batchRelationsPromise = pendingRelations.length > 0 ? mcpMutation(
|
|
2459
|
+
"chain.createEntryRelations",
|
|
2460
|
+
{
|
|
2461
|
+
relations: pendingRelations.slice(0, 25).map((r) => ({ fromEntryId: r.fromEntryId, toEntryId: r.toEntryId, type: r.type })),
|
|
2462
|
+
sessionId: agentId ?? void 0
|
|
2463
|
+
}
|
|
2464
|
+
).catch((err) => {
|
|
2465
|
+
entryWarnings.push(`Auto-linking partially failed: ${err instanceof Error ? err.message : "unknown error"}`);
|
|
2466
|
+
return null;
|
|
2467
|
+
}) : Promise.resolve(null);
|
|
2468
|
+
const cardinalityPromise = resolvedCK ? mcpQuery("chain.checkCardinalityWarning", { canonicalKey: resolvedCK }).catch(() => null) : Promise.resolve(null);
|
|
2469
|
+
const contradictionPromise = runContradictionCheck(name, description);
|
|
2470
|
+
const coachingPromise = mcpMutation("quality.evaluateHeuristicAndSchedule", {
|
|
2471
|
+
entryId: finalEntryId,
|
|
2472
|
+
context: "capture"
|
|
2473
|
+
}).catch(() => null);
|
|
2474
|
+
const [batchResult, cardinalityCheck, contradictionWarnings, verdictResult] = await Promise.all([
|
|
2475
|
+
batchRelationsPromise,
|
|
2476
|
+
cardinalityPromise,
|
|
2477
|
+
contradictionPromise,
|
|
2478
|
+
coachingPromise
|
|
2479
|
+
]);
|
|
2480
|
+
if (batchResult) {
|
|
2481
|
+
for (let i = 0; i < pendingRelations.length; i++) {
|
|
2482
|
+
const pending = pendingRelations[i];
|
|
2483
|
+
const result = batchResult.results[i];
|
|
2484
|
+
if (!result) continue;
|
|
2485
|
+
if (pending.meta.source === "auto") {
|
|
2486
|
+
if (result.ok) {
|
|
2487
|
+
linksCreated.push({
|
|
2488
|
+
targetEntryId: pending.toEntryId,
|
|
2489
|
+
targetName: pending.meta.targetName,
|
|
2490
|
+
targetCollection: pending.meta.targetCollection,
|
|
2491
|
+
relationType: pending.type,
|
|
2492
|
+
linkReason: pending.meta.linkReason
|
|
2493
|
+
});
|
|
2494
|
+
}
|
|
2495
|
+
} else {
|
|
2496
|
+
if (result.ok) {
|
|
2497
|
+
userLinkResults.push({ label: `\u2713 ${pending.type} \u2192 ${pending.toEntryId}`, ok: true });
|
|
2498
|
+
linksCreated.push({
|
|
2499
|
+
targetEntryId: pending.toEntryId,
|
|
2500
|
+
targetName: pending.meta.targetName,
|
|
2501
|
+
targetCollection: pending.meta.targetCollection,
|
|
2502
|
+
relationType: pending.type
|
|
2503
|
+
});
|
|
2504
|
+
} else {
|
|
2505
|
+
userLinkResults.push({ label: `\u2717 ${pending.type} \u2192 ${pending.toEntryId}: ${result.error ?? "failed"}`, ok: false });
|
|
2506
|
+
}
|
|
2411
2507
|
}
|
|
2412
2508
|
}
|
|
2413
2509
|
}
|
|
@@ -2424,34 +2520,13 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2424
2520
|
collectionFields: col.fields ?? []
|
|
2425
2521
|
};
|
|
2426
2522
|
const quality = scoreQuality(captureCtx, profile);
|
|
2427
|
-
|
|
2428
|
-
const resolvedCK = canonicalKey ?? captureCtx.canonicalKey;
|
|
2429
|
-
if (resolvedCK) {
|
|
2430
|
-
try {
|
|
2431
|
-
const check = await mcpQuery("chain.checkCardinalityWarning", {
|
|
2432
|
-
canonicalKey: resolvedCK
|
|
2433
|
-
});
|
|
2434
|
-
if (check?.warning) {
|
|
2435
|
-
cardinalityWarning = check.warning;
|
|
2436
|
-
}
|
|
2437
|
-
} catch {
|
|
2438
|
-
}
|
|
2439
|
-
}
|
|
2440
|
-
const contradictionWarnings = await runContradictionCheck(name, description);
|
|
2523
|
+
const cardinalityWarning = cardinalityCheck?.warning ?? null;
|
|
2441
2524
|
if (contradictionWarnings.length > 0) {
|
|
2442
2525
|
await recordSessionActivity({ contradictionWarning: true });
|
|
2443
2526
|
}
|
|
2444
2527
|
let coachingSection = "";
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
verdictResult = await mcpMutation("quality.evaluateHeuristicAndSchedule", {
|
|
2448
|
-
entryId: finalEntryId,
|
|
2449
|
-
context: "capture"
|
|
2450
|
-
});
|
|
2451
|
-
if (verdictResult?.verdict && verdictResult.verdict.tier !== "passive" && verdictResult.verdict.criteria.length > 0) {
|
|
2452
|
-
coachingSection = formatRubricCoaching(verdictResult);
|
|
2453
|
-
}
|
|
2454
|
-
} catch {
|
|
2528
|
+
if (verdictResult?.verdict && verdictResult.verdict.tier !== "passive" && verdictResult.verdict.criteria.length > 0) {
|
|
2529
|
+
coachingSection = formatRubricCoaching(verdictResult);
|
|
2455
2530
|
}
|
|
2456
2531
|
if (verdictResult?.verdict) {
|
|
2457
2532
|
try {
|
|
@@ -2596,6 +2671,13 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2596
2671
|
}
|
|
2597
2672
|
lines.push("Run `context action=gather` on these entries before committing.");
|
|
2598
2673
|
}
|
|
2674
|
+
if (entryWarnings.length > 0) {
|
|
2675
|
+
lines.push("");
|
|
2676
|
+
lines.push("## Validation Warnings");
|
|
2677
|
+
for (const w of entryWarnings) {
|
|
2678
|
+
lines.push(`- ${w}`);
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2599
2681
|
if (coachingSection) {
|
|
2600
2682
|
lines.push("");
|
|
2601
2683
|
lines.push(coachingSection);
|
|
@@ -2646,6 +2728,11 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2646
2728
|
next.push({ tool: "commit-entry", description: "Commit to Chain", parameters: { entryId: finalEntryId } });
|
|
2647
2729
|
}
|
|
2648
2730
|
const summary = finalStatus === "committed" ? `Captured and committed ${finalEntryId} (${name}) to ${resolvedCollection}. Quality ${quality.score}/10.` : finalStatus === "proposed" ? `Captured ${finalEntryId} (${name}) in ${resolvedCollection} and created a proposal for commit. Quality ${quality.score}/10.` : `Captured ${finalEntryId} (${name}) as draft in ${resolvedCollection}. Quality ${quality.score}/10.`;
|
|
2731
|
+
const expectedFields = (col.fields ?? []).map((f) => ({
|
|
2732
|
+
key: f.key,
|
|
2733
|
+
type: f.type,
|
|
2734
|
+
...f.required && { required: true }
|
|
2735
|
+
}));
|
|
2649
2736
|
const toolResult = {
|
|
2650
2737
|
content: [{ type: "text", text: lines.join("\n") }],
|
|
2651
2738
|
structuredContent: success(
|
|
@@ -2658,7 +2745,15 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2658
2745
|
qualityScore: quality.score,
|
|
2659
2746
|
qualityVerdict: verdictResult?.verdict ? { ...verdictResult.verdict, source: verdictResult.source ?? "heuristic" } : void 0,
|
|
2660
2747
|
...classifierMeta && { classifier: classifierMeta },
|
|
2661
|
-
...studioUrl && { studioUrl }
|
|
2748
|
+
...studioUrl && { studioUrl },
|
|
2749
|
+
...entryWarnings.length > 0 && { warnings: entryWarnings },
|
|
2750
|
+
...normalizationMeta && (Object.keys(normalizationMeta.remapped).length > 0 || normalizationMeta.rejected.length > 0) && {
|
|
2751
|
+
normalization: {
|
|
2752
|
+
remapped: normalizationMeta.remapped,
|
|
2753
|
+
rejected: normalizationMeta.rejected
|
|
2754
|
+
}
|
|
2755
|
+
},
|
|
2756
|
+
expectedFields
|
|
2662
2757
|
},
|
|
2663
2758
|
next
|
|
2664
2759
|
)
|
|
@@ -2759,19 +2854,8 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2759
2854
|
});
|
|
2760
2855
|
continue;
|
|
2761
2856
|
}
|
|
2762
|
-
const data =
|
|
2857
|
+
const data = buildDataFromFields(col.fields ?? [], profile.descriptionField, entry.description);
|
|
2763
2858
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
2764
|
-
for (const field of col.fields ?? []) {
|
|
2765
|
-
const key = field.key;
|
|
2766
|
-
if (key === profile.descriptionField) {
|
|
2767
|
-
data[key] = entry.description;
|
|
2768
|
-
} else if (field.type === "array" || field.type === "multi-select") {
|
|
2769
|
-
data[key] = [];
|
|
2770
|
-
} else if (field.type === "select") {
|
|
2771
|
-
} else {
|
|
2772
|
-
data[key] = "";
|
|
2773
|
-
}
|
|
2774
|
-
}
|
|
2775
2859
|
for (const def of profile.defaults) {
|
|
2776
2860
|
if (def.value === "today") data[def.key] = today;
|
|
2777
2861
|
else if (def.value !== "infer") data[def.key] = def.value;
|
|
@@ -2806,6 +2890,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2806
2890
|
});
|
|
2807
2891
|
const internalId = result.docId;
|
|
2808
2892
|
const finalEntryId = result.entryId;
|
|
2893
|
+
const batchEntryWarnings = result.warnings ?? [];
|
|
2809
2894
|
resolveGapsForEntry(entry.name, result.entryId);
|
|
2810
2895
|
let finalStatus = "draft";
|
|
2811
2896
|
let commitError;
|
|
@@ -2816,27 +2901,22 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2816
2901
|
const searchResults = await mcpQuery("chain.searchEntries", { query: searchQuery });
|
|
2817
2902
|
const candidates = (searchResults ?? []).filter((r) => r.entryId !== finalEntryId).map((r) => {
|
|
2818
2903
|
const conf = computeLinkConfidence(r, entry.name, entry.description, resolvedSlug, collIdToSlug.get(r.collectionId) ?? "unknown");
|
|
2819
|
-
return {
|
|
2820
|
-
...r,
|
|
2821
|
-
collSlug: collIdToSlug.get(r.collectionId) ?? "unknown",
|
|
2822
|
-
confidence: conf.score
|
|
2823
|
-
};
|
|
2904
|
+
return { ...r, collSlug: collIdToSlug.get(r.collectionId) ?? "unknown", confidence: conf.score };
|
|
2824
2905
|
}).sort((a, b) => b.confidence - a.confidence);
|
|
2906
|
+
const batchAutoLinks = [];
|
|
2825
2907
|
for (const c of candidates) {
|
|
2826
|
-
if (
|
|
2908
|
+
if (batchAutoLinks.length >= MAX_AUTO_LINKS) break;
|
|
2827
2909
|
if (c.confidence < AUTO_LINK_CONFIDENCE_THRESHOLD) break;
|
|
2828
2910
|
if (!c.entryId) continue;
|
|
2829
2911
|
const { type: relationType } = inferRelationType(resolvedSlug, c.collSlug, profile);
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
} catch {
|
|
2839
|
-
}
|
|
2912
|
+
batchAutoLinks.push({ fromEntryId: finalEntryId, toEntryId: c.entryId, type: relationType });
|
|
2913
|
+
}
|
|
2914
|
+
if (batchAutoLinks.length > 0) {
|
|
2915
|
+
const batchRes = await mcpMutation("chain.createEntryRelations", {
|
|
2916
|
+
relations: batchAutoLinks,
|
|
2917
|
+
sessionId: agentId ?? void 0
|
|
2918
|
+
});
|
|
2919
|
+
autoLinkCount = batchRes.created;
|
|
2840
2920
|
}
|
|
2841
2921
|
} catch {
|
|
2842
2922
|
}
|
|
@@ -2856,6 +2936,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2856
2936
|
commitError = error instanceof Error ? error.message : String(error);
|
|
2857
2937
|
}
|
|
2858
2938
|
}
|
|
2939
|
+
const entryNorm = result.normalization;
|
|
2859
2940
|
results.push({
|
|
2860
2941
|
name: entry.name,
|
|
2861
2942
|
collection: resolvedSlug,
|
|
@@ -2866,7 +2947,11 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2866
2947
|
classifiedBy,
|
|
2867
2948
|
confidence,
|
|
2868
2949
|
confidenceTier,
|
|
2869
|
-
...commitError ? { commitError } : {}
|
|
2950
|
+
...commitError ? { commitError } : {},
|
|
2951
|
+
...batchEntryWarnings.length > 0 ? { warnings: batchEntryWarnings } : {},
|
|
2952
|
+
...entryNorm && (Object.keys(entryNorm.remapped).length > 0 || entryNorm.rejected.length > 0) && {
|
|
2953
|
+
normalization: { remapped: entryNorm.remapped, rejected: entryNorm.rejected }
|
|
2954
|
+
}
|
|
2870
2955
|
});
|
|
2871
2956
|
} catch (error) {
|
|
2872
2957
|
const msg = error instanceof Error ? error.message : String(error);
|
|
@@ -2964,6 +3049,14 @@ _Use \`entries action=move\` to correct any misclassified entries._`);
|
|
|
2964
3049
|
lines.push(`- **${r.entryId}**: ${r.name} [${r.collection}] \u2014 ${r.commitError}`);
|
|
2965
3050
|
}
|
|
2966
3051
|
}
|
|
3052
|
+
const entriesWithWarnings = created.filter((r) => r.warnings && r.warnings.length > 0);
|
|
3053
|
+
if (entriesWithWarnings.length > 0) {
|
|
3054
|
+
lines.push("");
|
|
3055
|
+
lines.push("## Validation Warnings");
|
|
3056
|
+
for (const r of entriesWithWarnings) {
|
|
3057
|
+
lines.push(`- **${r.entryId}** (${r.name}): ${r.warnings.join("; ")}`);
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
2967
3060
|
if (failed.length > 0) {
|
|
2968
3061
|
lines.push("");
|
|
2969
3062
|
lines.push("## Failed");
|
|
@@ -3016,7 +3109,9 @@ _Use \`entries action=move\` to correct any misclassified entries._`);
|
|
|
3016
3109
|
status: r.status,
|
|
3017
3110
|
...r.classifiedBy ? { classifiedBy: r.classifiedBy } : {},
|
|
3018
3111
|
...r.confidence != null ? { confidence: r.confidence } : {},
|
|
3019
|
-
...r.confidenceTier ? { confidenceTier: r.confidenceTier } : {}
|
|
3112
|
+
...r.confidenceTier ? { confidenceTier: r.confidenceTier } : {},
|
|
3113
|
+
...r.warnings?.length ? { warnings: r.warnings } : {},
|
|
3114
|
+
...r.normalization ? { normalization: r.normalization } : {}
|
|
3020
3115
|
})),
|
|
3021
3116
|
total: created.length,
|
|
3022
3117
|
failed: failed.length,
|
|
@@ -3308,4 +3403,4 @@ export {
|
|
|
3308
3403
|
formatRubricCoaching,
|
|
3309
3404
|
formatRubricVerdictSection
|
|
3310
3405
|
};
|
|
3311
|
-
//# sourceMappingURL=chunk-
|
|
3406
|
+
//# sourceMappingURL=chunk-ZY3ORYC3.js.map
|