@rubytech/create-realagent 1.0.832 → 1.0.834
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/index.js +131 -9
- package/package.json +1 -1
- package/payload/platform/lib/admins-write/dist/index.d.ts +87 -0
- package/payload/platform/lib/admins-write/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/admins-write/dist/index.js +248 -0
- package/payload/platform/lib/admins-write/dist/index.js.map +1 -0
- package/payload/platform/lib/admins-write/src/index.ts +311 -0
- package/payload/platform/lib/admins-write/tsconfig.json +8 -0
- package/payload/platform/neo4j/migrations/009-conversation-archive-title.ts +197 -0
- package/payload/platform/neo4j/schema.cypher +1 -1
- package/payload/platform/package.json +2 -2
- package/payload/platform/plugins/admin/PLUGIN.md +1 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js +37 -44
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/docs/references/internals.md +4 -3
- package/payload/platform/plugins/memory/bin/conversation-archive-ingest.mjs +215 -43
- package/payload/platform/plugins/memory/bin/conversation-archive-ingest.sh +7 -2
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/llm-classifier.test.js +75 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/llm-classifier.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts +16 -10
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.js +155 -100
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.d.ts +13 -5
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.js +53 -59
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest.test.js +9 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts +24 -7
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +47 -11
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
- package/payload/platform/plugins/memory/skills/conversation-archive/SKILL.md +45 -8
- package/payload/platform/scripts/lib/resolve-account-dir.sh +3 -1
- package/payload/platform/scripts/migrate-import.sh +3 -1
- package/payload/platform/scripts/seed-neo4j.sh +13 -3
- package/payload/server/chunk-CRAIGEXY.js +654 -0
- package/payload/server/chunk-GK4WHM3H.js +9961 -0
- package/payload/server/chunk-I2NOLBQA.js +2123 -0
- package/payload/server/chunk-IVTESKFR.js +9961 -0
- package/payload/server/chunk-KD3XP4IK.js +1116 -0
- package/payload/server/chunk-KKGGT5RH.js +654 -0
- package/payload/server/chunk-MRJGG6CS.js +2124 -0
- package/payload/server/chunk-OJZPS4BL.js +367 -0
- package/payload/server/chunk-ZVW5XKPU.js +1116 -0
- package/payload/server/client-pool-FM3YJWV5.js +32 -0
- package/payload/server/client-pool-J5BCVVI2.js +32 -0
- package/payload/server/cloudflare-task-tracker-FSPEJOTH.js +19 -0
- package/payload/server/cloudflare-task-tracker-XCUO4N74.js +19 -0
- package/payload/server/maxy-edge.js +6 -5
- package/payload/server/neo4j-migrations-5AN2U3YO.js +664 -0
- package/payload/server/neo4j-migrations-XP7XDVPX.js +664 -0
- package/payload/server/public/assets/{Checkbox-CTGhpDKq.js → Checkbox-Bq6ORjz2.js} +1 -1
- package/payload/server/public/assets/admin-CstEkw-G.js +352 -0
- package/payload/server/public/assets/data-DwZZ7qbH.js +1 -0
- package/payload/server/public/assets/graph-DceEv42K.js +1 -0
- package/payload/server/public/assets/{jsx-runtime-D4WovFYk.css → jsx-runtime-DidQeNoZ.css} +1 -1
- package/payload/server/public/assets/page-Bpi_jPw6.js +50 -0
- package/payload/server/public/assets/{page-DkBfWy4C.js → page-CFWoVkgV.js} +1 -1
- package/payload/server/public/assets/{public-BdVIVpv8.js → public-BWMwq5Jj.js} +1 -1
- package/payload/server/public/assets/{useAdminFetch-DmHu0oCx.js → useAdminFetch-B93ig7ef.js} +1 -1
- package/payload/server/public/assets/{useVoiceRecorder-CSc_hxjV.js → useVoiceRecorder-Cb0nAtOo.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +8 -8
- package/payload/server/public/public.html +5 -5
- package/payload/server/server.js +376 -167
- package/payload/platform/plugins/admin/mcp/dist/lib/review-tools.d.ts +0 -31
- package/payload/platform/plugins/admin/mcp/dist/lib/review-tools.d.ts.map +0 -1
- package/payload/platform/plugins/admin/mcp/dist/lib/review-tools.js +0 -666
- package/payload/platform/plugins/admin/mcp/dist/lib/review-tools.js.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.d.ts +0 -61
- package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.d.ts.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.js +0 -266
- package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.js.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-pass.d.ts +0 -27
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-pass.d.ts.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-pass.js +0 -477
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-pass.js.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-write.d.ts +0 -27
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-write.d.ts.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-write.js +0 -160
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-write.js.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-parse.d.ts +0 -10
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-parse.d.ts.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-parse.js +0 -29
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-parse.js.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-preview.d.ts +0 -28
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-preview.d.ts.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-preview.js +0 -34
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-preview.js.map +0 -1
- package/payload/server/public/assets/admin-BNwPsMhJ.js +0 -352
- package/payload/server/public/assets/data-Y77FLKjs.js +0 -1
- package/payload/server/public/assets/graph-N_Bw-8oT.js +0 -1
- package/payload/server/public/assets/page-BKLGP-th.js +0 -50
- /package/payload/server/public/assets/{jsx-runtime-DkaAusaX.js → jsx-runtime-DH5S-MwB.js} +0 -0
|
@@ -24,11 +24,16 @@
|
|
|
24
24
|
// Argv (flags): --source <enum>
|
|
25
25
|
// --participant-person-ids <csv>
|
|
26
26
|
// --scope <admin|public>
|
|
27
|
-
// [--
|
|
27
|
+
// [--rebuild] (Task 902 — destructive rebuild)
|
|
28
28
|
// [--timezone <iana>]
|
|
29
29
|
// [--date-format <DD/MM/YY|MM/DD/YY|DD/MM/YYYY|MM/DD/YYYY>]
|
|
30
30
|
// [--session-id <id>]
|
|
31
31
|
//
|
|
32
|
+
// Sessions split at SESSION_GAP_HOURS=8 (fixed constant — Task 902). The flag
|
|
33
|
+
// `--session-gap-hours` is REMOVED; passing it FAILs at phase=argv. The
|
|
34
|
+
// chunked chat-mode classify path (Task 902 sub-scope C) absorbs oversize
|
|
35
|
+
// sessions internally — no operator lever required.
|
|
36
|
+
//
|
|
32
37
|
// Stdout (success): one JSON line — counters the skill needs to formulate
|
|
33
38
|
// the three operator-facing messages. See SKILL.md for the shape.
|
|
34
39
|
// Stderr + progress file: `[conversation-archive] ...` lines, fsync per write.
|
|
@@ -56,6 +61,16 @@ import { fileURLToPath } from "node:url";
|
|
|
56
61
|
|
|
57
62
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
58
63
|
|
|
64
|
+
// Task 902 sub-scope D — fixed session gap. Pre-902 this was a CLI flag with a
|
|
65
|
+
// 12h default; oversize sessions on dense archives drove operators to re-issue
|
|
66
|
+
// with a smaller gap, which combined with cleanup-by-archiveSha256 to silently
|
|
67
|
+
// destroy 138 chunks (Adam Mackay incident, 2026-05-04). The flag is gone;
|
|
68
|
+
// chunked chat-mode classify (sub-scope C) absorbs oversize sessions
|
|
69
|
+
// internally so the gap value is no longer an operational lever. 8h is a
|
|
70
|
+
// tighter default than 12h and matches the operator-decided post-incident
|
|
71
|
+
// constant.
|
|
72
|
+
const SESSION_GAP_HOURS = 8;
|
|
73
|
+
|
|
59
74
|
// ---------------------------------------------------------------------------
|
|
60
75
|
// 1. Resolve dist paths.
|
|
61
76
|
// ---------------------------------------------------------------------------
|
|
@@ -190,6 +205,9 @@ const VALID_SOURCES = new Set([
|
|
|
190
205
|
"other",
|
|
191
206
|
]);
|
|
192
207
|
|
|
208
|
+
// Boolean flags carry no value; every other flag consumes the following arg.
|
|
209
|
+
const BOOLEAN_FLAGS = new Set(["rebuild"]);
|
|
210
|
+
|
|
193
211
|
function parseArgv(argv) {
|
|
194
212
|
const args = argv.slice(2);
|
|
195
213
|
let archive = null;
|
|
@@ -202,6 +220,18 @@ function parseArgv(argv) {
|
|
|
202
220
|
continue;
|
|
203
221
|
}
|
|
204
222
|
const key = a.slice(2);
|
|
223
|
+
// Task 902 sub-scope D — the flag re-introduced the surface that enabled
|
|
224
|
+
// the silent-partial-wipe failure (Defect B). Reject loudly with the
|
|
225
|
+
// remediation the operator should use instead.
|
|
226
|
+
if (key === "session-gap-hours") {
|
|
227
|
+
fail("argv", {
|
|
228
|
+
reason: `--session-gap-hours is no longer supported; gap is fixed at 8h. Use --rebuild on the prior export bytes if you need to re-classify.`,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
if (BOOLEAN_FLAGS.has(camelCase(key))) {
|
|
232
|
+
flags[camelCase(key)] = true;
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
205
235
|
const v = args[++i];
|
|
206
236
|
if (v == null) fail("argv", { reason: `flag --${key} requires a value` });
|
|
207
237
|
flags[camelCase(key)] = v;
|
|
@@ -281,6 +311,87 @@ function findChatTxt(dir) {
|
|
|
281
311
|
return null;
|
|
282
312
|
}
|
|
283
313
|
|
|
314
|
+
// ---------------------------------------------------------------------------
|
|
315
|
+
// 4b. Stable archive title (Task 902 sub-scope A).
|
|
316
|
+
//
|
|
317
|
+
// Format: `<source> · <owner> ↔ <other1>, <other2>, … · <YYYY-MM-DD>→<YYYY-MM-DD>`.
|
|
318
|
+
//
|
|
319
|
+
// The title is computed once per ingest from inputs that are immutable for
|
|
320
|
+
// the conversation (source, accountId, sortedParticipantElementIds, archive
|
|
321
|
+
// dateRange) so re-ingests produce the same string. Memory-ingest writes it
|
|
322
|
+
// to `:ConversationArchive.title` ON CREATE and COALESCE-on-MATCH so the UI
|
|
323
|
+
// (display-helpers.ts) reads a stable label without ever falling through to
|
|
324
|
+
// `summary`. Per-session counter strings stay in the progress file only.
|
|
325
|
+
//
|
|
326
|
+
// Names: AdminUser uses `displayName` then `slug`; Person composes
|
|
327
|
+
// `givenName + familyName`. When neither resolves, fall back to a short
|
|
328
|
+
// elementId prefix — same degraded format the migration uses on backfill,
|
|
329
|
+
// so a re-ingest after the migration produces the same title shape that
|
|
330
|
+
// already populated the node.
|
|
331
|
+
// ---------------------------------------------------------------------------
|
|
332
|
+
|
|
333
|
+
function isoToYmd(iso) {
|
|
334
|
+
// Read the YYYY-MM-DD prefix verbatim — same tz-stable contract as
|
|
335
|
+
// formatRunDate in display-helpers.ts. Parsing to Date + reformatting
|
|
336
|
+
// would flip the day between operator timezones.
|
|
337
|
+
const m = typeof iso === "string" ? iso.match(/^(\d{4}-\d{2}-\d{2})/) : null;
|
|
338
|
+
return m ? m[1] : "?";
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function pickNameForRow(labels, props) {
|
|
342
|
+
if (Array.isArray(labels) && labels.includes("AdminUser")) {
|
|
343
|
+
const dn = typeof props.displayName === "string" ? props.displayName.trim() : "";
|
|
344
|
+
if (dn) return dn;
|
|
345
|
+
const slug = typeof props.slug === "string" ? props.slug.trim() : "";
|
|
346
|
+
if (slug) return slug;
|
|
347
|
+
}
|
|
348
|
+
if (Array.isArray(labels) && labels.includes("Person")) {
|
|
349
|
+
const given = typeof props.givenName === "string" ? props.givenName.trim() : "";
|
|
350
|
+
const family = typeof props.familyName === "string" ? props.familyName.trim() : "";
|
|
351
|
+
const full = [given, family].filter((s) => s.length > 0).join(" ");
|
|
352
|
+
if (full) return full;
|
|
353
|
+
}
|
|
354
|
+
return "";
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
async function computeArchiveTitle({
|
|
358
|
+
source,
|
|
359
|
+
accountId,
|
|
360
|
+
ownerElementId,
|
|
361
|
+
participantElementIds,
|
|
362
|
+
firstMessageAt,
|
|
363
|
+
lastMessageAt,
|
|
364
|
+
getSession,
|
|
365
|
+
}) {
|
|
366
|
+
const session = getSession();
|
|
367
|
+
let nameByElementId = new Map();
|
|
368
|
+
try {
|
|
369
|
+
const ids = [ownerElementId, ...participantElementIds];
|
|
370
|
+
const r = await session.run(
|
|
371
|
+
`UNWIND $ids AS id
|
|
372
|
+
MATCH (n) WHERE elementId(n) = id AND n.accountId = $accountId
|
|
373
|
+
RETURN elementId(n) AS elemId, labels(n) AS labels, properties(n) AS props`,
|
|
374
|
+
{ ids, accountId },
|
|
375
|
+
);
|
|
376
|
+
for (const rec of r.records) {
|
|
377
|
+
const elemId = rec.get("elemId");
|
|
378
|
+
const labels = rec.get("labels");
|
|
379
|
+
const props = rec.get("props") || {};
|
|
380
|
+
const name = pickNameForRow(labels, props);
|
|
381
|
+
if (name) nameByElementId.set(elemId, name);
|
|
382
|
+
}
|
|
383
|
+
} finally {
|
|
384
|
+
await session.close().catch(() => {});
|
|
385
|
+
}
|
|
386
|
+
const ownerName = nameByElementId.get(ownerElementId) || ownerElementId.slice(0, 8);
|
|
387
|
+
const otherNames = participantElementIds
|
|
388
|
+
.map((id) => nameByElementId.get(id) || id.slice(0, 8))
|
|
389
|
+
.join(", ");
|
|
390
|
+
const firstYmd = isoToYmd(firstMessageAt);
|
|
391
|
+
const lastYmd = isoToYmd(lastMessageAt);
|
|
392
|
+
return `${source} · ${ownerName} ↔ ${otherNames} · ${firstYmd}→${lastYmd}`;
|
|
393
|
+
}
|
|
394
|
+
|
|
284
395
|
// ---------------------------------------------------------------------------
|
|
285
396
|
// 5. Main
|
|
286
397
|
// ---------------------------------------------------------------------------
|
|
@@ -327,12 +438,12 @@ async function main() {
|
|
|
327
438
|
const scope = flags.scope;
|
|
328
439
|
const timezone = flags.timezone || "Europe/London";
|
|
329
440
|
const dateFormat = flags.dateFormat;
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
441
|
+
// Task 902 sub-scope B — `--rebuild` is the single opt-in for destructive
|
|
442
|
+
// re-run-with-same-bytes. Without it, re-issuing the bin on the same export
|
|
443
|
+
// is a no-op (chunk-count summary, exit 0). With it, the bin treats the run
|
|
444
|
+
// as first-ingest (skips prior-cursor lookup) and the FIRST session's
|
|
445
|
+
// memoryIngest call cleans prior chunks for the archiveSha256.
|
|
446
|
+
const rebuild = flags.rebuild === true;
|
|
336
447
|
const sessionId =
|
|
337
448
|
flags.sessionId ||
|
|
338
449
|
`conversation-archive:${source}:${Date.now()}:${Math.random().toString(36).slice(2, 10)}`;
|
|
@@ -426,7 +537,7 @@ async function main() {
|
|
|
426
537
|
const archiveSha256 = normaliserResult.archiveSha256;
|
|
427
538
|
const archiveSourceFile = normaliserResult.archiveSourceFile;
|
|
428
539
|
log(
|
|
429
|
-
`source=${source} file=${archiveSourceFile} owner=${ownerElementId} participants=${participantElementIds.length} scope=${scope} accountId=${accountId} archiveSha256=${archiveSha256.slice(0, 12)}
|
|
540
|
+
`source=${source} file=${archiveSourceFile} owner=${ownerElementId} participants=${participantElementIds.length} scope=${scope} accountId=${accountId} archiveSha256=${archiveSha256.slice(0, 12)} gap=${SESSION_GAP_HOURS} rebuild=${rebuild}`,
|
|
430
541
|
);
|
|
431
542
|
log(
|
|
432
543
|
`parsed lines=${normaliserResult.counters.parsed} media-skipped=${normaliserResult.counters.mediaSkipped} system-skipped=${normaliserResult.counters.systemSkipped}`,
|
|
@@ -463,38 +574,56 @@ async function main() {
|
|
|
463
574
|
fail("argv", { reason: err instanceof Error ? err.message : String(err) });
|
|
464
575
|
}
|
|
465
576
|
|
|
466
|
-
// 6d. Derive conversationIdentity and look up prior :ConversationArchive
|
|
577
|
+
// 6d. Derive conversationIdentity and look up prior :ConversationArchive.
|
|
578
|
+
// Task 902 sub-scope B — under `--rebuild` we skip the prior-cursor lookup
|
|
579
|
+
// entirely; the run is treated as first-ingest, the first session cleans
|
|
580
|
+
// prior chunks (cleanupPriorChunks=true), and the cursor is overwritten
|
|
581
|
+
// by that session's MERGE. Without `--rebuild`, the prior cursor drives
|
|
582
|
+
// delta-append OR (Task 902 sub-scope B) the same-bytes no-op exit when
|
|
583
|
+
// chunks already exist for this archiveSha256.
|
|
467
584
|
const conversationIdentity = deriveConversationIdentity({
|
|
468
585
|
accountId,
|
|
469
586
|
participantElementIds: [ownerElementId, ...participantElementIds],
|
|
470
587
|
});
|
|
471
588
|
let priorArchive = null;
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
589
|
+
let priorChunkCountForSha = 0;
|
|
590
|
+
if (!rebuild) {
|
|
591
|
+
try {
|
|
592
|
+
const r = await session.run(
|
|
593
|
+
`MATCH (a:ConversationArchive { conversationIdentity: $cid })
|
|
594
|
+
OPTIONAL MATCH (a)-[:HAS_SECTION]->(c:Section:Conversation { archiveSha256: $sha })
|
|
595
|
+
RETURN elementId(a) AS elemId,
|
|
596
|
+
a.lastIngestedMessageHash AS lastHash,
|
|
597
|
+
a.lastIngestedMessageAt AS lastAt,
|
|
598
|
+
count(c) AS chunksForSha LIMIT 1`,
|
|
599
|
+
{ cid: conversationIdentity, sha: archiveSha256 },
|
|
600
|
+
);
|
|
601
|
+
if (r.records[0] && r.records[0].get("elemId")) {
|
|
602
|
+
priorArchive = {
|
|
603
|
+
elemId: r.records[0].get("elemId"),
|
|
604
|
+
lastHash: r.records[0].get("lastHash"),
|
|
605
|
+
lastAt: r.records[0].get("lastAt"),
|
|
606
|
+
};
|
|
607
|
+
const cs = r.records[0].get("chunksForSha");
|
|
608
|
+
priorChunkCountForSha =
|
|
609
|
+
typeof cs === "number" ? cs : cs?.toNumber?.() ?? 0;
|
|
610
|
+
}
|
|
611
|
+
} catch (err) {
|
|
612
|
+
await session.close().catch(() => {});
|
|
613
|
+
cleanup();
|
|
614
|
+
fail("delta-cursor-missing", { reason: `conversationArchive lookup failed: ${err instanceof Error ? err.message : String(err)}` });
|
|
486
615
|
}
|
|
487
|
-
} catch (err) {
|
|
488
|
-
await session.close().catch(() => {});
|
|
489
|
-
cleanup();
|
|
490
|
-
fail("delta-cursor-missing", { reason: `conversationArchive lookup failed: ${err instanceof Error ? err.message : String(err)}` });
|
|
491
616
|
}
|
|
492
617
|
await session.close().catch(() => {});
|
|
493
618
|
|
|
494
|
-
// 6e. Compute deltaStart
|
|
619
|
+
// 6e. Compute deltaStart. Three branches:
|
|
620
|
+
// (i) --rebuild: deltaStart=0, kind=rebuild, classify entire archive.
|
|
621
|
+
// (ii) no prior archive (or no cursor): first-ingest, deltaStart=0.
|
|
622
|
+
// (iii) prior archive + cursor: standard delta-append. Same-bytes (no
|
|
623
|
+
// cursor advance possible) AND chunks exist for this sha → no-op.
|
|
495
624
|
let deltaStart = 0;
|
|
496
|
-
let deltaKind = "first-ingest";
|
|
497
|
-
if (priorArchive && priorArchive.lastHash) {
|
|
625
|
+
let deltaKind = rebuild ? "rebuild" : "first-ingest";
|
|
626
|
+
if (!rebuild && priorArchive && priorArchive.lastHash) {
|
|
498
627
|
const cursor = findDeltaCursor(allLines, priorArchive.lastHash);
|
|
499
628
|
if (cursor.kind === "missing") {
|
|
500
629
|
cleanup();
|
|
@@ -505,7 +634,7 @@ async function main() {
|
|
|
505
634
|
});
|
|
506
635
|
}
|
|
507
636
|
if (cursor.kind === "empty") {
|
|
508
|
-
log(`noop reason="no new messages since ${priorArchive.lastAt}"`);
|
|
637
|
+
log(`noop reason="no new messages since ${priorArchive.lastAt}" prior-chunks=${priorChunkCountForSha}`);
|
|
509
638
|
cleanup();
|
|
510
639
|
const totalMs = Date.now() - startedMs;
|
|
511
640
|
process.stdout.write(JSON.stringify({
|
|
@@ -519,7 +648,7 @@ async function main() {
|
|
|
519
648
|
systemSkipped: normaliserResult.counters.systemSkipped,
|
|
520
649
|
delta: { kind: "empty-delta", deltaStart: allLines.length, deltaMessages: 0 },
|
|
521
650
|
sessions: 0,
|
|
522
|
-
chunks:
|
|
651
|
+
chunks: priorChunkCountForSha,
|
|
523
652
|
nextEdgesCreated: 0,
|
|
524
653
|
participantsLinked: 0,
|
|
525
654
|
dateRange: { first: allLines[0].dateSent, last: allLines[allLines.length - 1].dateSent },
|
|
@@ -536,15 +665,31 @@ async function main() {
|
|
|
536
665
|
}
|
|
537
666
|
const deltaLines = allLines.slice(deltaStart);
|
|
538
667
|
log(
|
|
539
|
-
`delta cursor=${priorArchive ? priorArchive.lastHash.slice(0, 12) : "(first-ingest)"} cursor-line=${deltaStart} delta-messages=${deltaLines.length}`,
|
|
668
|
+
`delta kind=${deltaKind} cursor=${priorArchive && priorArchive.lastHash && !rebuild ? priorArchive.lastHash.slice(0, 12) : "(first-ingest)"} cursor-line=${deltaStart} delta-messages=${deltaLines.length}`,
|
|
540
669
|
);
|
|
541
670
|
|
|
542
|
-
// 6f. Sessionize delta
|
|
543
|
-
const sessions = sessionize(deltaLines,
|
|
671
|
+
// 6f. Sessionize delta at the fixed 8h gap (Task 902 sub-scope D).
|
|
672
|
+
const sessions = sessionize(deltaLines, SESSION_GAP_HOURS);
|
|
544
673
|
log(
|
|
545
|
-
`sessionize source=${source} archiveSha256=${archiveSha256.slice(0, 12)} messages=${deltaLines.length} sessions=${sessions.length} gap-hours=${
|
|
674
|
+
`sessionize source=${source} archiveSha256=${archiveSha256.slice(0, 12)} messages=${deltaLines.length} sessions=${sessions.length} gap-hours=${SESSION_GAP_HOURS}`,
|
|
546
675
|
);
|
|
547
676
|
|
|
677
|
+
// Task 902 sub-scope A — compute the stable archive title once, before
|
|
678
|
+
// the per-session loop. The title is `<source> · <owner> ↔ <others> ·
|
|
679
|
+
// <YYYY-MM-DD>→<YYYY-MM-DD>`. Operator-confirmed participant names come
|
|
680
|
+
// from one Cypher hop; absent canonical names fall back to elementId
|
|
681
|
+
// prefixes so the migration's degraded-title path mirrors live behaviour.
|
|
682
|
+
const archiveTitle = await computeArchiveTitle({
|
|
683
|
+
source,
|
|
684
|
+
accountId,
|
|
685
|
+
ownerElementId,
|
|
686
|
+
participantElementIds,
|
|
687
|
+
firstMessageAt: allLines[0].dateSent,
|
|
688
|
+
lastMessageAt: allLines[allLines.length - 1].dateSent,
|
|
689
|
+
getSession,
|
|
690
|
+
});
|
|
691
|
+
log(`archive-title=${archiveTitle}`);
|
|
692
|
+
|
|
548
693
|
// 6g. Per-session classify + immediate memoryIngest (Task 900 sub-scope E).
|
|
549
694
|
// Each session commits atomically: chunks + cursor advance happen together
|
|
550
695
|
// via memoryIngest. A kill mid-loop leaves a partial archive whose cursor
|
|
@@ -621,7 +766,6 @@ async function main() {
|
|
|
621
766
|
body: lastSessionLine.body,
|
|
622
767
|
});
|
|
623
768
|
const sessionLastAt = lastSessionLine.dateSent;
|
|
624
|
-
const sessionDocumentSummary = `Session ${s.index + 1}/${sessions.length}: ${s.messages.length} messages, ${sessionChunks.length} chunks.`;
|
|
625
769
|
|
|
626
770
|
let ingestResult;
|
|
627
771
|
const ingestStart = Date.now();
|
|
@@ -631,7 +775,13 @@ async function main() {
|
|
|
631
775
|
attachmentId: conversationIdentity,
|
|
632
776
|
parentLabel: "ConversationArchive",
|
|
633
777
|
source,
|
|
634
|
-
|
|
778
|
+
// Task 902 sub-scope A — `archiveTitle` is the stable label written
|
|
779
|
+
// to `:ConversationArchive.title` (UI prefers it over `summary`).
|
|
780
|
+
// `documentSummary` is also the stable title rather than the
|
|
781
|
+
// per-session counter that previously locked the parent's first
|
|
782
|
+
// checkpoint into "Session 1/N: …".
|
|
783
|
+
archiveTitle,
|
|
784
|
+
documentSummary: archiveTitle,
|
|
635
785
|
anchorNodeId: ownerElementId,
|
|
636
786
|
anchorLabel: "AdminUser",
|
|
637
787
|
sections: sessionChunks,
|
|
@@ -643,11 +793,11 @@ async function main() {
|
|
|
643
793
|
lastIngestedMessageHash: sessionLastHash,
|
|
644
794
|
lastIngestedMessageAt: sessionLastAt,
|
|
645
795
|
participantElementIds: [ownerElementId, ...participantElementIds],
|
|
646
|
-
//
|
|
647
|
-
//
|
|
648
|
-
// sessions
|
|
649
|
-
//
|
|
650
|
-
cleanupPriorChunks: isFirstSessionInRun,
|
|
796
|
+
// Task 902 sub-scope B — cleanup-by-archiveSha256 runs ONLY under
|
|
797
|
+
// `--rebuild`, AND only on the first session of the run (subsequent
|
|
798
|
+
// sessions skip cleanup or they would delete chunks the earlier
|
|
799
|
+
// sessions in the same run just wrote).
|
|
800
|
+
cleanupPriorChunks: rebuild && isFirstSessionInRun,
|
|
651
801
|
});
|
|
652
802
|
} catch (err) {
|
|
653
803
|
cleanup();
|
|
@@ -663,10 +813,32 @@ async function main() {
|
|
|
663
813
|
totalNextEdges += ingestResult.edgeBreakdown.NEXT ?? 0;
|
|
664
814
|
if (isFirstSessionInRun) {
|
|
665
815
|
participantsLinked = ingestResult.edgeBreakdown.PARTICIPANT_IN ?? 0;
|
|
816
|
+
// Task 902 sub-scope E — surface destructive cleanup as a WARN line in
|
|
817
|
+
// the progress sink (not just memory-ingest's stderr). The agent's
|
|
818
|
+
// heartbeat grep-matches this exact prefix and elevates to operator
|
|
819
|
+
// chat. Cleanup only ever fires under `--rebuild` per sub-scope B,
|
|
820
|
+
// so seeing the line outside of an operator-issued `--rebuild` is a
|
|
821
|
+
// doctrine violation worth surfacing loudly.
|
|
822
|
+
const cleaned = ingestResult.cleanedPriorChunks ?? 0;
|
|
823
|
+
if (cleaned > 0) {
|
|
824
|
+
log(
|
|
825
|
+
`WARN cleanup-dropped chunks=${cleaned} archiveSha256=${archiveSha256.slice(0, 12)} — prior data deleted, expected only under --rebuild`,
|
|
826
|
+
);
|
|
827
|
+
}
|
|
666
828
|
}
|
|
667
829
|
log(
|
|
668
830
|
`session-committed sessionIndex=${s.index + 1}/${sessions.length} chunks-written=${ingestResult.sectionCount} cursor-at="${sessionLastAt}" ms=${Date.now() - ingestStart}`,
|
|
669
831
|
);
|
|
832
|
+
// Task 902 sub-scope F — derived progress line. The agent's heartbeat
|
|
833
|
+
// surfaces only `progress` lines as chat tokens; raw `classify-session`
|
|
834
|
+
// and `session-committed` lines remain on disk for diagnosis. The render
|
|
835
|
+
// is computed in the bin (deterministic) instead of in SKILL.md prose
|
|
836
|
+
// (LLM drift) — sessionIndex/N → P% with running totals comes from one
|
|
837
|
+
// place, not from per-tick agent arithmetic.
|
|
838
|
+
const pct = Math.round((100 * (s.index + 1)) / sessions.length);
|
|
839
|
+
log(
|
|
840
|
+
`progress sessionIndex=${s.index + 1}/${sessions.length} pct=${pct} chunks-so-far=${totalChunksWritten} elapsed-ms=${Date.now() - startedMs}`,
|
|
841
|
+
);
|
|
670
842
|
}
|
|
671
843
|
|
|
672
844
|
if (sessionsUnenriched > 0) {
|
|
@@ -18,11 +18,14 @@
|
|
|
18
18
|
# --source <whatsapp|telegram|signal|linkedin-messages|zoom-transcript|meeting-minutes|imessage|slack|other>
|
|
19
19
|
# --participant-person-ids <csv>
|
|
20
20
|
# --scope <admin|public>
|
|
21
|
-
# [--
|
|
21
|
+
# [--rebuild] (Task 902 — opt-in destructive rebuild)
|
|
22
22
|
# [--timezone <iana-zone>]
|
|
23
23
|
# [--date-format <DD/MM/YY|MM/DD/YY|DD/MM/YYYY|MM/DD/YYYY>] (whatsapp only)
|
|
24
24
|
# [--session-id <id>]
|
|
25
25
|
#
|
|
26
|
+
# Sessions split deterministically at 8h gap (fixed code constant — Task 902).
|
|
27
|
+
# `--session-gap-hours` is REMOVED; passing it FAILs at phase=argv.
|
|
28
|
+
#
|
|
26
29
|
# Identity (Task 900): `ACCOUNT_ID` + `USER_ID` come from the caller's env
|
|
27
30
|
# (plumbed by `spawn-env.ts` into every Bash subprocess). The owner :AdminUser
|
|
28
31
|
# elementId is derived from (accountId, userId) inside the bin via Cypher.
|
|
@@ -82,7 +85,9 @@ while [ $i -lt ${#ARGS[@]} ]; do
|
|
|
82
85
|
--participant-person-ids) HAS_PARTICIPANTS=1; PARTICIPANTS_VAL="${ARGS[$((i + 1))]:-}"; i=$((i + 2)); continue ;;
|
|
83
86
|
--scope) HAS_SCOPE=1; SCOPE_VAL="${ARGS[$((i + 1))]:-}"; i=$((i + 2)); continue ;;
|
|
84
87
|
--session-id) SESSION_ID_VAL="${ARGS[$((i + 1))]:-}"; i=$((i + 2)); continue ;;
|
|
85
|
-
--
|
|
88
|
+
--rebuild) i=$((i + 1)); continue ;;
|
|
89
|
+
--session-gap-hours) arg_fail "--session-gap-hours is no longer supported; gap is fixed at 8h. Use --rebuild on the prior export bytes if you need to re-classify." ;;
|
|
90
|
+
--timezone|--date-format) i=$((i + 2)); continue ;;
|
|
86
91
|
--*) i=$((i + 2)); continue ;;
|
|
87
92
|
*)
|
|
88
93
|
if [ -z "$ARCHIVE" ]; then ARCHIVE="$a"; fi
|
|
@@ -139,6 +139,81 @@ test("Task 891: classifyDocument logs `mode=` for grep parity", () => {
|
|
|
139
139
|
const source = readClassifier();
|
|
140
140
|
assert.match(source, /\[memory-classify\][^\n]*calling haiku[^\n]*mode=/, "calling-haiku log line must include `mode=<document|chat>` for grep parity");
|
|
141
141
|
});
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
// Task 898 — classifier + ranker structured tool-use migration.
|
|
144
|
+
//
|
|
145
|
+
// The classifier and ranker now force Haiku to emit `tool_use.input` matching
|
|
146
|
+
// a typed `input_schema`. The migration deletes `extractJson` (used to strip
|
|
147
|
+
// markdown fences from a free-form text response) and the malformed-JSON
|
|
148
|
+
// fallback path entirely — Anthropic enforces the schema at the API boundary,
|
|
149
|
+
// so structural failures (missing fields, wrong types, truncation mid-tool-input)
|
|
150
|
+
// surface as fallback responses or as the existing missing-offsets loud-fail.
|
|
151
|
+
//
|
|
152
|
+
// These tests grep source so a future refactor that reverts to free-form text
|
|
153
|
+
// re-fails the test suite on `main` pre-fix.
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
const RANKER_PATH = resolve(PACKAGE_ROOT, "src/lib/llm-ranker.ts");
|
|
156
|
+
function readRanker() {
|
|
157
|
+
return readFileSync(RANKER_PATH, "utf-8");
|
|
158
|
+
}
|
|
159
|
+
test("Task 898: classifier defines a ClassifierOutputTool with input_schema", () => {
|
|
160
|
+
const source = readClassifier();
|
|
161
|
+
assert.match(source, /ClassifierOutputTool[\s\S]{0,200}name:\s*["']emit_classifier_output["']/, "classifier must export a ClassifierOutputTool whose name is 'emit_classifier_output'");
|
|
162
|
+
assert.match(source, /ClassifierOutputTool[\s\S]*?input_schema/, "ClassifierOutputTool must declare an input_schema");
|
|
163
|
+
});
|
|
164
|
+
test("Task 898: classifier call site forces tool selection", () => {
|
|
165
|
+
const source = readClassifier();
|
|
166
|
+
const callMatch = source.match(/callOauthLlm\(\{[\s\S]*?\}\)/);
|
|
167
|
+
assert.ok(callMatch, "expected to find callOauthLlm({...}) call site");
|
|
168
|
+
assert.match(callMatch[0], /tools:\s*\[ClassifierOutputTool\]/, "classifier MUST pass `tools: [ClassifierOutputTool]` so Haiku emits structured output");
|
|
169
|
+
assert.match(callMatch[0], /toolChoiceName:\s*ClassifierOutputTool\.name/, "classifier MUST force the tool by name — Anthropic only validates the schema when forced");
|
|
170
|
+
});
|
|
171
|
+
test("Task 898: classifier `kind` schema is enforced as an enum (closed enumeration)", () => {
|
|
172
|
+
const source = readClassifier();
|
|
173
|
+
// The schema must declare `kind` with an `enum` whose membership is sourced
|
|
174
|
+
// from ALL_SECTION_KINDS. We check the structural shape rather than the
|
|
175
|
+
// exact list — the list is exported and tested elsewhere.
|
|
176
|
+
assert.match(source, /kind:\s*\{\s*type:\s*["']string["'],\s*enum:\s*ALL_SECTION_KINDS_LIST/, "ClassifierOutputTool.input_schema must enforce `kind` as an enum sourced from ALL_SECTION_KINDS — schema-level enforcement is what makes hallucinated kinds impossible");
|
|
177
|
+
});
|
|
178
|
+
test("Task 898: classifier no longer references extractJson (dead code removed)", () => {
|
|
179
|
+
const source = readClassifier();
|
|
180
|
+
assert.doesNotMatch(source, /extractJson/, "extractJson is unreachable on the structured-output path and was deleted; reintroducing it is the regression");
|
|
181
|
+
});
|
|
182
|
+
test("Task 898: classifier no longer collapses unknown kinds to Other (unreachable on structured path)", () => {
|
|
183
|
+
const source = readClassifier();
|
|
184
|
+
// The pre-Task-898 collapse used `isKnownKind ? rawKind : SECTION_KIND_OTHER`.
|
|
185
|
+
// With a strict schema enum on `kind`, the collapse is unreachable. The
|
|
186
|
+
// variable name is the load-bearing fingerprint of the dead branch.
|
|
187
|
+
assert.doesNotMatch(source, /isKnownKind/, "the `isKnownKind` collapse is dead code on the structured path; reintroducing it weakens the schema-as-enforcement contract");
|
|
188
|
+
});
|
|
189
|
+
test("Task 898: classifier emits `structured-output ok` log line per call", () => {
|
|
190
|
+
const source = readClassifier();
|
|
191
|
+
assert.match(source, /\[memory-classify\][^\n]*structured-output ok[^\n]*stop-reason=/, "classifier must log `structured-output ok stop-reason=...` per call so observability names the structured path");
|
|
192
|
+
});
|
|
193
|
+
test("Task 898: ranker defines a RankerOutputTool with input_schema", () => {
|
|
194
|
+
const source = readRanker();
|
|
195
|
+
assert.match(source, /RankerOutputTool[\s\S]{0,200}name:\s*["']emit_ranker_output["']/, "ranker must export a RankerOutputTool whose name is 'emit_ranker_output'");
|
|
196
|
+
assert.match(source, /RankerOutputTool[\s\S]*?input_schema/, "RankerOutputTool must declare an input_schema");
|
|
197
|
+
});
|
|
198
|
+
test("Task 898: ranker call site forces tool selection", () => {
|
|
199
|
+
const source = readRanker();
|
|
200
|
+
const callMatch = source.match(/callOauthLlm\(\{[\s\S]*?\}\)/);
|
|
201
|
+
assert.ok(callMatch, "expected to find callOauthLlm({...}) call site");
|
|
202
|
+
assert.match(callMatch[0], /tools:\s*\[RankerOutputTool\]/, "ranker MUST pass `tools: [RankerOutputTool]`");
|
|
203
|
+
assert.match(callMatch[0], /toolChoiceName:\s*RankerOutputTool\.name/, "ranker MUST force the tool by name");
|
|
204
|
+
});
|
|
205
|
+
test("Task 898: ranker no longer references extractJson", () => {
|
|
206
|
+
const source = readRanker();
|
|
207
|
+
assert.doesNotMatch(source, /extractJson/, "extractJson is unreachable on the structured-output path and was deleted");
|
|
208
|
+
});
|
|
209
|
+
test("Task 898: ranker no longer parses JSON.parse on response text", () => {
|
|
210
|
+
const source = readRanker();
|
|
211
|
+
assert.doesNotMatch(source, /JSON\.parse\(jsonText\)/, "structured tool-use returns a typed object — JSON.parse on response text is dead code");
|
|
212
|
+
});
|
|
213
|
+
test("Task 898: ranker emits `structured-output ok` log line per call", () => {
|
|
214
|
+
const source = readRanker();
|
|
215
|
+
assert.match(source, /\[memory-rank\][^\n]*structured-output ok[^\n]*stop-reason=/, "ranker must log `structured-output ok stop-reason=...` per call");
|
|
216
|
+
});
|
|
142
217
|
test("Task 781 fixture is still >=10K chars (regression anchor)", () => {
|
|
143
218
|
// The fixture is named in the brief so the same evidence shape can be
|
|
144
219
|
// re-run on demand. If it ever shrinks below 10K, this test fails loud
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-classifier.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/llm-classifier.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"llm-classifier.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/llm-classifier.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,14 +14,18 @@
|
|
|
14
14
|
* the Anthropic API key. The API-key path is reserved for the public
|
|
15
15
|
* agent.
|
|
16
16
|
*
|
|
17
|
-
* Hallucination defence:
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
17
|
+
* Hallucination defence: section `kind` is enforced as a closed enum in
|
|
18
|
+
* `ClassifierOutputTool.input_schema`, so a hallucinated kind cannot reach
|
|
19
|
+
* this module — Anthropic rejects the tool_use input at the API boundary.
|
|
20
|
+
* For `related[].kind` and `documentEdges[].targetKind` (which the static
|
|
21
|
+
* schema cannot constrain because the live ontology label set is a runtime
|
|
22
|
+
* input), the post-validator drops any label not in `ontologyLabels`.
|
|
23
|
+
* Failure of the LLM call (missing creds, network, schema-violating
|
|
24
|
+
* `tool_use.input`) returns `{kind: "error", reason}`. The caller decides
|
|
25
|
+
* whether to abort the ingest or degrade-on-error per session; classifier
|
|
26
|
+
* never silently substitutes a degraded write.
|
|
24
27
|
*/
|
|
28
|
+
import { type OauthLlmTool } from "../../../../../lib/oauth-llm/dist/index.js";
|
|
25
29
|
/** Direction of the anchor edge relative to the typed node. */
|
|
26
30
|
export type AnchorEdgeDirection = "from-anchor" | "to-anchor";
|
|
27
31
|
/** Direction of a related-node edge relative to the typed node. */
|
|
@@ -166,9 +170,10 @@ export type ClassifyResult = {
|
|
|
166
170
|
};
|
|
167
171
|
/**
|
|
168
172
|
* Closed enumeration of section `kind` values. Each becomes a secondary
|
|
169
|
-
* label on the `:Section` node (e.g. `:Section:Position`).
|
|
170
|
-
*
|
|
171
|
-
*
|
|
173
|
+
* label on the `:Section` node (e.g. `:Section:Position`). The `kind` field
|
|
174
|
+
* is enforced as an `enum` in `ClassifierOutputTool.input_schema`, so a
|
|
175
|
+
* hallucinated kind cannot reach the post-validator — Anthropic rejects the
|
|
176
|
+
* tool_use input at the API boundary (Task 898).
|
|
172
177
|
*
|
|
173
178
|
* Source of truth: schema-base.md "Section kinds" table. Changes here MUST
|
|
174
179
|
* be mirrored there or the validator will reject the secondary label.
|
|
@@ -180,6 +185,7 @@ export declare const CONTRACT_SECTION_KINDS: readonly ["Parties", "Recitals", "D
|
|
|
180
185
|
/** Standalone (non-Section) node kind the classifier may emit per section. */
|
|
181
186
|
export declare const STANDALONE_NODE_KINDS: readonly ["Project"];
|
|
182
187
|
export declare const ALL_SECTION_KINDS: ReadonlySet<string>;
|
|
188
|
+
export declare const ClassifierOutputTool: OauthLlmTool;
|
|
183
189
|
export interface ClassifyParams {
|
|
184
190
|
/** Account scope, for log prefixing. */
|
|
185
191
|
accountId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-classifier.d.ts","sourceRoot":"","sources":["../../src/lib/llm-classifier.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"llm-classifier.d.ts","sourceRoot":"","sources":["../../src/lib/llm-classifier.ts"],"names":[],"mappings":"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"}
|