@agentproto/corpus 0.1.0-alpha.3 → 0.1.0-alpha.4
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-3P23OX5X.mjs → chunk-JV6VRZ6U.mjs} +2 -2
- package/dist/chunk-JV6VRZ6U.mjs.map +1 -0
- package/dist/index.d.ts +373 -10
- package/dist/index.mjs +329 -35
- package/dist/index.mjs.map +1 -1
- package/dist/report/index.mjs +1 -1
- package/package.json +5 -5
- package/dist/chunk-3P23OX5X.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { systemClock } from './chunk-KYX2DTEH.mjs';
|
|
2
|
-
import { REFINED_KIND_SCHEMA, resolveKnowledge } from './chunk-
|
|
3
|
-
export { REFINED_KIND_SCHEMA, isRefinedKind, resolveKnowledge } from './chunk-
|
|
2
|
+
import { REFINED_KIND_SCHEMA, resolveKnowledge } from './chunk-JV6VRZ6U.mjs';
|
|
3
|
+
export { REFINED_KIND_SCHEMA, isRefinedKind, resolveKnowledge } from './chunk-JV6VRZ6U.mjs';
|
|
4
4
|
import { CandidatesSidecar } from './chunk-UPX26MYH.mjs';
|
|
5
5
|
export { CandidatesSidecar, SidecarDuplicateError, SidecarNotFoundError } from './chunk-UPX26MYH.mjs';
|
|
6
|
-
import
|
|
6
|
+
import matter6 from 'gray-matter';
|
|
7
7
|
import { createHash } from 'crypto';
|
|
8
8
|
import { z } from 'zod';
|
|
9
9
|
import { parse, stringify } from 'yaml';
|
|
@@ -379,7 +379,7 @@ var CorpusWorkspaceReader = class {
|
|
|
379
379
|
};
|
|
380
380
|
for (const path of mdFiles) {
|
|
381
381
|
const content = await this.opts.fs.readFile(path);
|
|
382
|
-
const parsed =
|
|
382
|
+
const parsed = matter6(content);
|
|
383
383
|
const file = {
|
|
384
384
|
// Workspace-relative path. The walk returns paths anchored at
|
|
385
385
|
// the host's storage root (which already includes `root` for
|
|
@@ -535,7 +535,7 @@ var CorpusWorkspaceWriter = class _CorpusWorkspaceWriter {
|
|
|
535
535
|
}
|
|
536
536
|
};
|
|
537
537
|
function serializeMarkdown(doc) {
|
|
538
|
-
return
|
|
538
|
+
return matter6.stringify(doc.body.startsWith("\n") ? doc.body : "\n" + doc.body, doc.frontmatter);
|
|
539
539
|
}
|
|
540
540
|
|
|
541
541
|
// src/importers/runner.ts
|
|
@@ -673,7 +673,7 @@ function serializeSource(source, archiveDirSegment, clock) {
|
|
|
673
673
|
}
|
|
674
674
|
};
|
|
675
675
|
}
|
|
676
|
-
return
|
|
676
|
+
return matter6.stringify(
|
|
677
677
|
source.body.startsWith("\n") ? source.body : "\n" + source.body,
|
|
678
678
|
fm
|
|
679
679
|
);
|
|
@@ -995,7 +995,9 @@ var DistillRunner = class {
|
|
|
995
995
|
const items = await this.opts.distiller.distill({
|
|
996
996
|
title: source.title,
|
|
997
997
|
body: source.body,
|
|
998
|
-
...source.tags ? { tags: source.tags } : {}
|
|
998
|
+
...source.tags ? { tags: source.tags } : {},
|
|
999
|
+
...source.kinds ? { kinds: source.kinds } : {},
|
|
1000
|
+
...source.instruction ? { instruction: source.instruction } : {}
|
|
999
1001
|
});
|
|
1000
1002
|
const year = this.opts.clock.now().getUTCFullYear();
|
|
1001
1003
|
const flat = this.opts.layout === "flat";
|
|
@@ -1028,7 +1030,7 @@ function serializeEntry(item, slug, source, clock) {
|
|
|
1028
1030
|
sources: [source.id],
|
|
1029
1031
|
// ← derivedFrom / provenance edge
|
|
1030
1032
|
confidence: typeof item.confidence === "number" ? item.confidence : 0.7,
|
|
1031
|
-
tags: dedupeTags(item.tags, source.tags),
|
|
1033
|
+
tags: withAspect(dedupeTags(item.tags, source.tags), source.aspect),
|
|
1032
1034
|
metadata: {
|
|
1033
1035
|
corpus: {
|
|
1034
1036
|
status: "active",
|
|
@@ -1042,7 +1044,14 @@ function serializeEntry(item, slug, source, clock) {
|
|
|
1042
1044
|
}
|
|
1043
1045
|
};
|
|
1044
1046
|
const body = item.body.trim();
|
|
1045
|
-
return
|
|
1047
|
+
return matter6.stringify(body.startsWith("\n") ? body : "\n" + body, fm);
|
|
1048
|
+
}
|
|
1049
|
+
function withAspect(tags, aspect) {
|
|
1050
|
+
if (!aspect) return [...tags];
|
|
1051
|
+
const value = sanitizeTag(aspect);
|
|
1052
|
+
if (!value) return [...tags];
|
|
1053
|
+
const facet = `aspect:${value}`;
|
|
1054
|
+
return tags.includes(facet) ? [...tags] : [facet, ...tags];
|
|
1046
1055
|
}
|
|
1047
1056
|
function dedupeTags(a, b) {
|
|
1048
1057
|
const out = /* @__PURE__ */ new Set();
|
|
@@ -1064,10 +1073,16 @@ var DISTILLED_ITEM = z.object({
|
|
|
1064
1073
|
tags: z.array(z.string()).optional()
|
|
1065
1074
|
}).loose();
|
|
1066
1075
|
function buildDistillPrompt(input, maxItems) {
|
|
1067
|
-
|
|
1076
|
+
const lensBlock = input.instruction?.trim() ? `LENS \u2014 read the source THROUGH this aspect, extract ONLY what serves it:
|
|
1077
|
+
${input.instruction.trim()}
|
|
1078
|
+
|
|
1079
|
+
` : "";
|
|
1080
|
+
const kinds = input.kinds?.length ? input.kinds : ["principle", "pattern", "critique", "summary", "example"];
|
|
1081
|
+
const kindUnion = kinds.map((k) => `"${k}"`).join(" | ");
|
|
1082
|
+
return `${lensBlock}You distill a raw source (a video transcript or article) into REFINED, reusable knowledge for an AI operator. Extract the durable insights \u2014 not a summary of the video, but the transferable lessons.
|
|
1068
1083
|
|
|
1069
1084
|
Return a JSON array (max ${maxItems} items). Each item:
|
|
1070
|
-
{ "kind": one of
|
|
1085
|
+
{ "kind": one of ${kindUnion},
|
|
1071
1086
|
"title": short imperative/declarative title,
|
|
1072
1087
|
"body": 2-5 sentences, SELF-CONTAINED (no "the speaker says"), the actual insight,
|
|
1073
1088
|
"confidence": 0-1, "tags": [short topic tags] }
|
|
@@ -1125,7 +1140,7 @@ async function scanDistilledSourceIds(fs) {
|
|
|
1125
1140
|
if (!rel.endsWith(".md")) continue;
|
|
1126
1141
|
const path = rel.startsWith("entries/") ? rel : `entries/${rel}`;
|
|
1127
1142
|
try {
|
|
1128
|
-
const fm = ENTRY_SOURCES.parse(
|
|
1143
|
+
const fm = ENTRY_SOURCES.parse(matter6(await fs.readFile(path)).data);
|
|
1129
1144
|
if (fm.sources) for (const s of fm.sources) ids.add(s);
|
|
1130
1145
|
} catch {
|
|
1131
1146
|
}
|
|
@@ -1174,47 +1189,309 @@ function createDistillRegistry() {
|
|
|
1174
1189
|
};
|
|
1175
1190
|
}
|
|
1176
1191
|
|
|
1177
|
-
// src/distill/
|
|
1178
|
-
|
|
1192
|
+
// src/distill/lens.ts
|
|
1193
|
+
function lensAspect(lens) {
|
|
1194
|
+
return lens.aspect ?? lens.id;
|
|
1195
|
+
}
|
|
1196
|
+
function lensAspectTag(lens) {
|
|
1197
|
+
return `aspect:${lensAspect(lens)}`;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
// src/distill/generate.ts
|
|
1201
|
+
async function distillFromImporter(opts) {
|
|
1179
1202
|
const report = {
|
|
1180
|
-
descriptorId: descriptor.id,
|
|
1181
|
-
scopeId: scope.id,
|
|
1182
1203
|
unitsConsidered: 0,
|
|
1183
1204
|
unitsDistilled: 0,
|
|
1184
1205
|
entriesWritten: 0,
|
|
1185
|
-
skipped: 0
|
|
1206
|
+
skipped: 0,
|
|
1207
|
+
unchanged: 0
|
|
1186
1208
|
};
|
|
1187
|
-
const target = await descriptor.target(scope);
|
|
1188
|
-
const distilled = await scanDistilledSourceIds(target.fs);
|
|
1189
|
-
const binding = descriptor.bind(scope, target);
|
|
1190
|
-
const config = await binding.prepare(distilled);
|
|
1191
|
-
if (!config) return report;
|
|
1192
1209
|
const runner = new DistillRunner({
|
|
1193
|
-
fs:
|
|
1194
|
-
clock:
|
|
1195
|
-
distiller:
|
|
1210
|
+
fs: opts.fs,
|
|
1211
|
+
clock: opts.clock,
|
|
1212
|
+
distiller: opts.distiller,
|
|
1213
|
+
...opts.layout ? { layout: opts.layout } : {}
|
|
1196
1214
|
});
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1215
|
+
const provenanceId = opts.provenanceId ?? ((s) => s.slug);
|
|
1216
|
+
const lensId = opts.lens?.id;
|
|
1217
|
+
for await (const imported of opts.importer.enumerate({
|
|
1218
|
+
importerId: opts.importerId,
|
|
1219
|
+
config: opts.config
|
|
1200
1220
|
})) {
|
|
1201
1221
|
report.unitsConsidered++;
|
|
1222
|
+
const sourceId = provenanceId(imported);
|
|
1223
|
+
if (opts.index && await opts.index.isDistilled(sourceId, imported.contentHash, lensId)) {
|
|
1224
|
+
report.unchanged++;
|
|
1225
|
+
continue;
|
|
1226
|
+
}
|
|
1202
1227
|
const source = {
|
|
1203
|
-
id:
|
|
1228
|
+
id: sourceId,
|
|
1204
1229
|
title: imported.title,
|
|
1205
1230
|
body: imported.body,
|
|
1206
|
-
...imported.tags ? { tags: imported.tags } : {}
|
|
1231
|
+
...imported.tags ? { tags: imported.tags } : {},
|
|
1232
|
+
...opts.lens?.prompt ? { instruction: opts.lens.prompt } : {},
|
|
1233
|
+
...opts.lens?.kinds ? { kinds: opts.lens.kinds } : {},
|
|
1234
|
+
...opts.lens ? { aspect: lensAspect(opts.lens) } : {}
|
|
1207
1235
|
};
|
|
1208
1236
|
try {
|
|
1209
1237
|
const r = await runner.run(source);
|
|
1210
1238
|
if (r.entryPaths.length > 0) report.unitsDistilled++;
|
|
1211
1239
|
report.entriesWritten += r.entryPaths.length;
|
|
1212
1240
|
report.skipped += r.skipped.length;
|
|
1241
|
+
if (opts.index) {
|
|
1242
|
+
await opts.index.record({
|
|
1243
|
+
sourceId,
|
|
1244
|
+
...lensId ? { lensId } : {},
|
|
1245
|
+
title: imported.title,
|
|
1246
|
+
distilledAt: opts.clock.now().toISOString(),
|
|
1247
|
+
...opts.engine ? { engine: opts.engine } : {},
|
|
1248
|
+
...imported.contentHash ? { contentHash: imported.contentHash } : {},
|
|
1249
|
+
entryCount: r.entryPaths.length,
|
|
1250
|
+
...r.entryPaths.length ? { entryPaths: r.entryPaths } : {}
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1213
1253
|
} catch {
|
|
1214
1254
|
}
|
|
1215
1255
|
}
|
|
1216
1256
|
return report;
|
|
1217
1257
|
}
|
|
1258
|
+
|
|
1259
|
+
// src/distill/run.ts
|
|
1260
|
+
async function runDistill(descriptor, scope, opts = {}) {
|
|
1261
|
+
const empty = {
|
|
1262
|
+
unitsConsidered: 0,
|
|
1263
|
+
unitsDistilled: 0,
|
|
1264
|
+
entriesWritten: 0,
|
|
1265
|
+
skipped: 0,
|
|
1266
|
+
unchanged: 0
|
|
1267
|
+
};
|
|
1268
|
+
const target = await descriptor.target(scope);
|
|
1269
|
+
const distilled = await scanDistilledSourceIds(target.fs);
|
|
1270
|
+
const binding = descriptor.bind(scope, target);
|
|
1271
|
+
const config = await binding.prepare(distilled);
|
|
1272
|
+
if (!config) {
|
|
1273
|
+
return { descriptorId: descriptor.id, scopeId: scope.id, ...empty };
|
|
1274
|
+
}
|
|
1275
|
+
const core = await distillFromImporter({
|
|
1276
|
+
fs: target.fs,
|
|
1277
|
+
clock: target.clock,
|
|
1278
|
+
distiller: descriptor.distiller(scope),
|
|
1279
|
+
importer: binding.importer,
|
|
1280
|
+
importerId: descriptor.id,
|
|
1281
|
+
config,
|
|
1282
|
+
provenanceId: binding.provenanceId,
|
|
1283
|
+
...opts.index ? { index: opts.index } : {},
|
|
1284
|
+
...opts.engine ? { engine: opts.engine } : {},
|
|
1285
|
+
...opts.lens ? { lens: opts.lens } : {}
|
|
1286
|
+
});
|
|
1287
|
+
return { descriptorId: descriptor.id, scopeId: scope.id, ...core };
|
|
1288
|
+
}
|
|
1289
|
+
var DISTILL_INDEX_PATH = "_distill-index.yaml";
|
|
1290
|
+
var DistillIndex = class {
|
|
1291
|
+
fs;
|
|
1292
|
+
path;
|
|
1293
|
+
constructor(opts) {
|
|
1294
|
+
this.fs = opts.fs;
|
|
1295
|
+
this.path = opts.path ?? DISTILL_INDEX_PATH;
|
|
1296
|
+
}
|
|
1297
|
+
/** Every record on disk. Empty for a fresh corpus (no file yet). */
|
|
1298
|
+
async load() {
|
|
1299
|
+
if (!await this.fs.exists(this.path)) return [];
|
|
1300
|
+
const content = await this.fs.readFile(this.path);
|
|
1301
|
+
if (!content.trim()) return [];
|
|
1302
|
+
const parsed = parse(content);
|
|
1303
|
+
if (!parsed || !Array.isArray(parsed.runs)) return [];
|
|
1304
|
+
return parsed.runs;
|
|
1305
|
+
}
|
|
1306
|
+
/**
|
|
1307
|
+
* The record for a `(sourceId, lensId)` pair, or null if never distilled.
|
|
1308
|
+
* `lensId` undefined matches the generic lens-less row (back-compat).
|
|
1309
|
+
*/
|
|
1310
|
+
async get(sourceId, lensId) {
|
|
1311
|
+
const rows = await this.load();
|
|
1312
|
+
return rows.find((r) => r.sourceId === sourceId && r.lensId === lensId) ?? null;
|
|
1313
|
+
}
|
|
1314
|
+
/**
|
|
1315
|
+
* True if the `(source, lens)` pair was distilled with a matching content
|
|
1316
|
+
* hash (when given). Each lens has independent cadence over the same source.
|
|
1317
|
+
*/
|
|
1318
|
+
async isDistilled(sourceId, contentHash, lensId) {
|
|
1319
|
+
const row = await this.get(sourceId, lensId);
|
|
1320
|
+
if (!row) return false;
|
|
1321
|
+
if (contentHash === void 0) return true;
|
|
1322
|
+
return row.contentHash === contentHash;
|
|
1323
|
+
}
|
|
1324
|
+
/**
|
|
1325
|
+
* Upsert a record by `(sourceId, lensId)`. Re-distilling overwrites that
|
|
1326
|
+
* pair's row (cadence is "latest run wins") while leaving the same source's
|
|
1327
|
+
* other lens rows untouched; a new pair appends. Returns the full list.
|
|
1328
|
+
*/
|
|
1329
|
+
async record(row) {
|
|
1330
|
+
const existing = await this.load();
|
|
1331
|
+
const idx = existing.findIndex(
|
|
1332
|
+
(r) => r.sourceId === row.sourceId && r.lensId === row.lensId
|
|
1333
|
+
);
|
|
1334
|
+
const next = idx === -1 ? [...existing, row] : [...existing.slice(0, idx), row, ...existing.slice(idx + 1)];
|
|
1335
|
+
await this.write(next);
|
|
1336
|
+
return next;
|
|
1337
|
+
}
|
|
1338
|
+
/** Whole-file replace. Prefer {@link record} for normal flow. */
|
|
1339
|
+
async write(runs) {
|
|
1340
|
+
const shape = { runs };
|
|
1341
|
+
await this.fs.writeFile(this.path, stringify(shape));
|
|
1342
|
+
}
|
|
1343
|
+
};
|
|
1344
|
+
var SYNTHESIS_ROLE_TAG = "role:synthesis";
|
|
1345
|
+
var ATOM_FRONTMATTER = z.object({
|
|
1346
|
+
schema: z.string().optional().catch(void 0),
|
|
1347
|
+
slug: z.string().optional().catch(void 0),
|
|
1348
|
+
title: z.string().optional().catch(void 0),
|
|
1349
|
+
sources: z.array(z.string()).optional().catch(void 0),
|
|
1350
|
+
confidence: z.number().optional().catch(void 0),
|
|
1351
|
+
tags: z.array(z.string()).optional().catch(void 0),
|
|
1352
|
+
supersedes: z.array(z.string()).optional().catch(void 0),
|
|
1353
|
+
metadata: z.object({
|
|
1354
|
+
corpus: z.object({ status: z.string().optional().catch(void 0) }).loose().optional().catch(void 0)
|
|
1355
|
+
}).loose().optional().catch(void 0)
|
|
1356
|
+
}).loose();
|
|
1357
|
+
async function readEntries(fs) {
|
|
1358
|
+
let rels;
|
|
1359
|
+
try {
|
|
1360
|
+
rels = await fs.walk("entries");
|
|
1361
|
+
} catch {
|
|
1362
|
+
return [];
|
|
1363
|
+
}
|
|
1364
|
+
const out = [];
|
|
1365
|
+
for (const rel of rels) {
|
|
1366
|
+
if (!rel.endsWith(".md")) continue;
|
|
1367
|
+
const path = `entries/${rel}`;
|
|
1368
|
+
let parsed;
|
|
1369
|
+
try {
|
|
1370
|
+
parsed = matter6(await fs.readFile(path));
|
|
1371
|
+
} catch {
|
|
1372
|
+
continue;
|
|
1373
|
+
}
|
|
1374
|
+
const fm = ATOM_FRONTMATTER.parse(parsed.data);
|
|
1375
|
+
if (fm.schema !== "knowledge.entry/v1") continue;
|
|
1376
|
+
const tags = fm.tags ?? [];
|
|
1377
|
+
out.push({
|
|
1378
|
+
slug: fm.slug ?? path,
|
|
1379
|
+
title: fm.title ?? "",
|
|
1380
|
+
body: parsed.content.trim(),
|
|
1381
|
+
confidence: fm.confidence ?? 0,
|
|
1382
|
+
tags,
|
|
1383
|
+
supersedes: fm.supersedes ?? [],
|
|
1384
|
+
path,
|
|
1385
|
+
archived: fm.metadata?.corpus?.status === "archived",
|
|
1386
|
+
isSynthesis: tags.includes(SYNTHESIS_ROLE_TAG)
|
|
1387
|
+
});
|
|
1388
|
+
}
|
|
1389
|
+
return out;
|
|
1390
|
+
}
|
|
1391
|
+
async function currentLensAtoms(fs, lens) {
|
|
1392
|
+
const aspectTag = lensAspectTag(lens);
|
|
1393
|
+
const entries = await readEntries(fs);
|
|
1394
|
+
const superseded = /* @__PURE__ */ new Set();
|
|
1395
|
+
for (const e of entries) for (const s of e.supersedes) superseded.add(s);
|
|
1396
|
+
return entries.filter(
|
|
1397
|
+
(e) => !e.archived && !e.isSynthesis && e.tags.includes(aspectTag) && !superseded.has(e.slug)
|
|
1398
|
+
).sort((a, b) => b.confidence - a.confidence).map((e) => ({ slug: e.slug, title: e.title, body: e.body }));
|
|
1399
|
+
}
|
|
1400
|
+
function defaultSynthesisPath(lens) {
|
|
1401
|
+
return `entries/summaries/${lensAspect(lens)}-knowledge.md`;
|
|
1402
|
+
}
|
|
1403
|
+
async function lensSynthesisStale(fs, lens) {
|
|
1404
|
+
const atoms = await currentLensAtoms(fs, lens);
|
|
1405
|
+
const atomSlugs = new Set(atoms.map((a) => a.slug));
|
|
1406
|
+
const path = lens.synthesisPath ?? defaultSynthesisPath(lens);
|
|
1407
|
+
if (!await fs.exists(path)) {
|
|
1408
|
+
return { stale: atoms.length > 0, reason: atoms.length > 0 ? "missing" : "fresh", atomCount: atoms.length };
|
|
1409
|
+
}
|
|
1410
|
+
let recorded = [];
|
|
1411
|
+
try {
|
|
1412
|
+
const fm = ATOM_FRONTMATTER.parse(matter6(await fs.readFile(path)).data);
|
|
1413
|
+
recorded = fm.sources ?? [];
|
|
1414
|
+
} catch {
|
|
1415
|
+
return { stale: true, reason: "drifted", atomCount: atoms.length };
|
|
1416
|
+
}
|
|
1417
|
+
const recordedSet = new Set(recorded);
|
|
1418
|
+
const same = recordedSet.size === atomSlugs.size && [...atomSlugs].every((s) => recordedSet.has(s));
|
|
1419
|
+
return {
|
|
1420
|
+
stale: !same,
|
|
1421
|
+
reason: same ? "fresh" : "drifted",
|
|
1422
|
+
atomCount: atoms.length
|
|
1423
|
+
};
|
|
1424
|
+
}
|
|
1425
|
+
async function synthesizeLens(opts) {
|
|
1426
|
+
const { fs, clock, synthesizer, lens } = opts;
|
|
1427
|
+
const aspect = lensAspect(lens);
|
|
1428
|
+
const entries = await readEntries(fs);
|
|
1429
|
+
const aspectTag = lensAspectTag(lens);
|
|
1430
|
+
const considered = entries.filter(
|
|
1431
|
+
(e) => !e.archived && !e.isSynthesis && e.tags.includes(aspectTag)
|
|
1432
|
+
).length;
|
|
1433
|
+
const atoms = await currentLensAtoms(fs, lens);
|
|
1434
|
+
if (atoms.length === 0) {
|
|
1435
|
+
return { lensId: lens.id, aspect, atomsConsidered: considered, atomsUsed: 0, wrote: false };
|
|
1436
|
+
}
|
|
1437
|
+
const body = await synthesizer.synthesize({ aspect, label: lens.label, atoms });
|
|
1438
|
+
const path = lens.synthesisPath ?? defaultSynthesisPath(lens);
|
|
1439
|
+
await fs.writeFile(path, serializeSynthesis(body, lens, atoms, clock));
|
|
1440
|
+
return {
|
|
1441
|
+
lensId: lens.id,
|
|
1442
|
+
aspect,
|
|
1443
|
+
atomsConsidered: considered,
|
|
1444
|
+
atomsUsed: atoms.length,
|
|
1445
|
+
wrote: true,
|
|
1446
|
+
path
|
|
1447
|
+
};
|
|
1448
|
+
}
|
|
1449
|
+
function serializeSynthesis(body, lens, atoms, clock) {
|
|
1450
|
+
const now = clock.now().toISOString();
|
|
1451
|
+
const slug = `${lensAspect(lens)}-knowledge`;
|
|
1452
|
+
const fm = {
|
|
1453
|
+
schema: "knowledge.entry/v1",
|
|
1454
|
+
slug,
|
|
1455
|
+
kind: "summary",
|
|
1456
|
+
title: `${lens.label} \u2014 current view`,
|
|
1457
|
+
updated_at: now,
|
|
1458
|
+
// Provenance: the atoms this synthesis consolidates (derivedFrom edges).
|
|
1459
|
+
sources: atoms.map((a) => a.slug),
|
|
1460
|
+
confidence: 0.8,
|
|
1461
|
+
// Faceted aspect tag + the synthesis role marker (kept verbatim — both are
|
|
1462
|
+
// AIP-10 facet structure, not plain tags, so they bypass the topic sanitizer).
|
|
1463
|
+
tags: [lensAspectTag(lens), SYNTHESIS_ROLE_TAG],
|
|
1464
|
+
metadata: {
|
|
1465
|
+
corpus: {
|
|
1466
|
+
status: "active",
|
|
1467
|
+
promotionMode: "lens-synthesis",
|
|
1468
|
+
promotedAt: now,
|
|
1469
|
+
lens: lens.id
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
};
|
|
1473
|
+
const trimmed = body.trim();
|
|
1474
|
+
return matter6.stringify(trimmed.startsWith("\n") ? trimmed : "\n" + trimmed, fm);
|
|
1475
|
+
}
|
|
1476
|
+
function buildSynthesisPrompt(input) {
|
|
1477
|
+
const atomBlock = input.atoms.map((a, i) => `### Atom ${i + 1}: ${a.title}
|
|
1478
|
+
${a.body}`).join("\n\n");
|
|
1479
|
+
return `You consolidate the CURRENT knowledge of one aspect into a single living document for an AI operator. You are given the current (non-superseded) atoms \u2014 each a durable insight already extracted. Earlier reversed decisions have already been removed, so treat every atom as currently true.
|
|
1480
|
+
|
|
1481
|
+
ASPECT: ${input.aspect} (${input.label})
|
|
1482
|
+
|
|
1483
|
+
Write a coherent, well-structured markdown document that:
|
|
1484
|
+
- Synthesizes the atoms into a unified current view \u2014 not a list, a narrative the operator can act on.
|
|
1485
|
+
- Resolves overlaps; group related atoms under headings.
|
|
1486
|
+
- States the CURRENT position plainly. Do not hedge with "previously" / "it was decided" \u2014 this is the present truth.
|
|
1487
|
+
- Stays grounded ONLY in the atoms; invent nothing.
|
|
1488
|
+
- Writes in ENGLISH.
|
|
1489
|
+
|
|
1490
|
+
CURRENT ATOMS:
|
|
1491
|
+
${atomBlock}
|
|
1492
|
+
|
|
1493
|
+
Return ONLY the markdown document body (no frontmatter, no code fence).`;
|
|
1494
|
+
}
|
|
1218
1495
|
var ANTHROPIC_RESPONSE = z.object({
|
|
1219
1496
|
content: z.array(
|
|
1220
1497
|
z.object({ type: z.string(), text: z.string().optional() }).loose()
|
|
@@ -2523,6 +2800,20 @@ var CorpusIndexer = class {
|
|
|
2523
2800
|
let removed = 0;
|
|
2524
2801
|
let skipped = 0;
|
|
2525
2802
|
let chunkCount = 0;
|
|
2803
|
+
let sourcesPushed = 0;
|
|
2804
|
+
if (this.opts.writer.pushSource) {
|
|
2805
|
+
for (const source of snapshot.sources) {
|
|
2806
|
+
const sourceId = source.frontmatter.id;
|
|
2807
|
+
if (typeof sourceId !== "string") continue;
|
|
2808
|
+
await this.opts.writer.pushSource({
|
|
2809
|
+
sourceId,
|
|
2810
|
+
sourcePath: source.path,
|
|
2811
|
+
title: typeof source.frontmatter.title === "string" ? source.frontmatter.title : void 0,
|
|
2812
|
+
sourceFrontmatter: source.frontmatter
|
|
2813
|
+
});
|
|
2814
|
+
sourcesPushed++;
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2526
2817
|
for (const entry of snapshot.entries) {
|
|
2527
2818
|
const status = readStatus(entry);
|
|
2528
2819
|
if (status === "active") {
|
|
@@ -2539,7 +2830,7 @@ var CorpusIndexer = class {
|
|
|
2539
2830
|
skipped++;
|
|
2540
2831
|
}
|
|
2541
2832
|
}
|
|
2542
|
-
return { pushed, removed, skipped, chunkCount };
|
|
2833
|
+
return { pushed, removed, skipped, chunkCount, sourcesPushed };
|
|
2543
2834
|
}
|
|
2544
2835
|
/**
|
|
2545
2836
|
* Re-sync a single entry by slug. The lifecycle's `promote`
|
|
@@ -2585,7 +2876,10 @@ var CorpusIndexer = class {
|
|
|
2585
2876
|
confidence: entry.frontmatter.confidence,
|
|
2586
2877
|
tags: entry.frontmatter.tags,
|
|
2587
2878
|
...corpus
|
|
2588
|
-
}
|
|
2879
|
+
},
|
|
2880
|
+
// Full frontmatter for a graph-projection writer (relation arrays the
|
|
2881
|
+
// flattened entryMetadata drops). Vector engines ignore it.
|
|
2882
|
+
entryFrontmatter: entry.frontmatter
|
|
2589
2883
|
});
|
|
2590
2884
|
return chunks.length;
|
|
2591
2885
|
}
|
|
@@ -3102,7 +3396,7 @@ var PlaybookLifecycle = class {
|
|
|
3102
3396
|
async writeWith(playbook, patch) {
|
|
3103
3397
|
const writer = new CorpusWorkspaceWriter({ fs: this.opts.fs });
|
|
3104
3398
|
const nextFm = patch({ ...playbook.file.frontmatter });
|
|
3105
|
-
const nextContent =
|
|
3399
|
+
const nextContent = matter6.stringify(
|
|
3106
3400
|
playbook.body.startsWith("\n") ? playbook.body : "\n" + playbook.body,
|
|
3107
3401
|
nextFm
|
|
3108
3402
|
);
|
|
@@ -3270,7 +3564,7 @@ var PlaybookEvaluator = class {
|
|
|
3270
3564
|
note: `n=${metrics.sampleSize} winRate=${metrics.winRateVsBaseline.toFixed(3)}`
|
|
3271
3565
|
})
|
|
3272
3566
|
);
|
|
3273
|
-
const content =
|
|
3567
|
+
const content = matter6.stringify(
|
|
3274
3568
|
playbook.body.startsWith("\n") ? playbook.body : "\n" + playbook.body,
|
|
3275
3569
|
fm
|
|
3276
3570
|
);
|
|
@@ -3309,6 +3603,6 @@ function joinPath5(a, b) {
|
|
|
3309
3603
|
var SPEC_NAME = "agentcorpus/v1";
|
|
3310
3604
|
var SPEC_VERSION = "0.1.0-alpha";
|
|
3311
3605
|
|
|
3312
|
-
export { ANY_REF, ClaudeDistiller, ConversationImporter, CorpusEventEmitter, CorpusIndexer, CorpusLinter, CorpusPromoter, CorpusValidator, CorpusVersionConflictError, CorpusWorkspaceReader, CorpusWorkspaceWriter, DEFAULT_TRANSITIONS, DistillRunner, EMPTY_SELECTOR, IllegalPlaybookTransitionError, IllegalTransitionError, ImporterRunner, KbMigrationImporter, LocalFilesImporter, MemFs, OperatorOverlayResolver, OverlayFs, PlaybookEvaluator, PlaybookLifecycle, PlaybookNotFoundError, PlaybookRegistry, PromoteRejectedError, ReadOnlyFs, ReviewerTrackRecord, SPEC_NAME, SPEC_VERSION, StackResolver, SyncRunner, WELL_KNOWN_AXES, WHITEOUT_SUFFIX, WebImporter, aggregateReviewerScores, appendAttestation, assertTransition, buildDistillPrompt, buildOverlayFromStack, canTransition, capabilityAxis, chunkText, compileLegacyPlaybookBinding, computeReviewerCalibration, createAxisRegistry, createDistillRegistry, enumerateWindowRefs, evaluateAccess, evaluateCapability, evaluateGate, extractAutoPromoteConfig, flattenPackRefs, identityAxis, isEmptySelector, isEntrySlug, isSourceSlug, makeAttestation, matchAttachmentRefs, matchAttachments, matchesLanguageFilter, matchesSelector, modelDistiller, normalizeLanguageTag, parseItems, parseSelectorFrontmatter, parseWindowRef, partitionStackRefs, pearsonCorrelation, positionAxis, prefixedRefNormalizer, readAccessModes, readAccessSpec, readAttestations, readEntryLanguage, readOperatorLocale, readWorkspaceDefaultLanguage, renderOverlays, resolveLanguageFilter, roleAxis, runDistill, scanDistilledSourceIds, slugify, transitionGraphFromCollection, uniqueSlug, windowRef, windowSlug };
|
|
3606
|
+
export { ANY_REF, ClaudeDistiller, ConversationImporter, CorpusEventEmitter, CorpusIndexer, CorpusLinter, CorpusPromoter, CorpusValidator, CorpusVersionConflictError, CorpusWorkspaceReader, CorpusWorkspaceWriter, DEFAULT_TRANSITIONS, DISTILL_INDEX_PATH, DistillIndex, DistillRunner, EMPTY_SELECTOR, IllegalPlaybookTransitionError, IllegalTransitionError, ImporterRunner, KbMigrationImporter, LocalFilesImporter, MemFs, OperatorOverlayResolver, OverlayFs, PlaybookEvaluator, PlaybookLifecycle, PlaybookNotFoundError, PlaybookRegistry, PromoteRejectedError, ReadOnlyFs, ReviewerTrackRecord, SPEC_NAME, SPEC_VERSION, SYNTHESIS_ROLE_TAG, StackResolver, SyncRunner, WELL_KNOWN_AXES, WHITEOUT_SUFFIX, WebImporter, aggregateReviewerScores, appendAttestation, assertTransition, buildDistillPrompt, buildOverlayFromStack, buildSynthesisPrompt, canTransition, capabilityAxis, chunkText, compileLegacyPlaybookBinding, computeReviewerCalibration, createAxisRegistry, createDistillRegistry, currentLensAtoms, defaultSynthesisPath, distillFromImporter, enumerateWindowRefs, evaluateAccess, evaluateCapability, evaluateGate, extractAutoPromoteConfig, flattenPackRefs, identityAxis, isEmptySelector, isEntrySlug, isSourceSlug, lensAspect, lensAspectTag, lensSynthesisStale, makeAttestation, matchAttachmentRefs, matchAttachments, matchesLanguageFilter, matchesSelector, modelDistiller, normalizeLanguageTag, parseItems, parseSelectorFrontmatter, parseWindowRef, partitionStackRefs, pearsonCorrelation, positionAxis, prefixedRefNormalizer, readAccessModes, readAccessSpec, readAttestations, readEntryLanguage, readOperatorLocale, readWorkspaceDefaultLanguage, renderOverlays, resolveLanguageFilter, roleAxis, runDistill, scanDistilledSourceIds, slugify, synthesizeLens, transitionGraphFromCollection, uniqueSlug, windowRef, windowSlug };
|
|
3313
3607
|
//# sourceMappingURL=index.mjs.map
|
|
3314
3608
|
//# sourceMappingURL=index.mjs.map
|