@rubytech/create-realagent 1.0.830 → 1.0.831
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/package.json +1 -1
- package/payload/platform/lib/oauth-llm/dist/index.d.ts +8 -1
- package/payload/platform/lib/oauth-llm/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/oauth-llm/dist/index.js +5 -1
- package/payload/platform/lib/oauth-llm/dist/index.js.map +1 -1
- package/payload/platform/lib/oauth-llm/src/index.ts +19 -4
- package/payload/platform/neo4j/migrations/008-adminuser-accountid-backfill.ts +85 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js +25 -3
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/docs/references/internals.md +1 -1
- package/payload/platform/plugins/memory/bin/conversation-archive-ingest.mjs +50 -27
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/timestamp-scanner.d.ts +49 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/timestamp-scanner.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/timestamp-scanner.js +35 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/timestamp-scanner.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.d.ts +6 -7
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.js +9 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/whatsapp-text.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/whatsapp-text.js +49 -131
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/whatsapp-text.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/delta-cursor.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/delta-cursor.js +0 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/delta-cursor.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/derive-keys.d.ts +0 -2
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/derive-keys.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/derive-keys.js +10 -11
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/derive-keys.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/sender-bind.d.ts +3 -4
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/sender-bind.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/sender-bind.js +11 -42
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/sender-bind.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/to-turn-text.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/to-turn-text.js +10 -8
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/to-turn-text.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts +10 -8
- 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 +118 -43
- 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 +3 -2
- 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 +40 -18
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-normalisers-source-agnosticism.test.js +4 -6
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-normalisers-source-agnosticism.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-normalisers-whatsapp-text.test.js +59 -17
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-normalisers-whatsapp-text.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-rank.js +2 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-rank.js.map +1 -1
- package/payload/server/chunk-BCFM2UPH.js +2305 -0
- package/payload/server/chunk-CV3HPX46.js +10097 -0
- package/payload/server/chunk-J6YWEJBN.js +1116 -0
- package/payload/server/chunk-OCPJGZ6S.js +654 -0
- package/payload/server/client-pool-ZNGN66GN.js +32 -0
- package/payload/server/cloudflare-task-tracker-MHALDN54.js +19 -0
- package/payload/server/maxy-edge.js +3 -3
- package/payload/server/neo4j-migrations-6RW423E2.js +530 -0
- package/payload/server/server.js +30 -19
|
@@ -269,17 +269,17 @@ async function main() {
|
|
|
269
269
|
// Imports — fail loudly if any compiled dist missing
|
|
270
270
|
let getNormaliser;
|
|
271
271
|
let sessionize, toTurnText, findDeltaCursor;
|
|
272
|
-
let
|
|
273
|
-
let
|
|
272
|
+
let deriveConversationIdentity, deriveMessageContentHash;
|
|
273
|
+
let verifyParticipantElementIds;
|
|
274
274
|
let getSession, classifyDocument, memoryIngest;
|
|
275
275
|
try {
|
|
276
276
|
({ getNormaliser } = await import(NORMALISERS_PATH));
|
|
277
277
|
({ sessionize } = await import(join(PIPELINE_PATH, "sessionize.js")));
|
|
278
278
|
({ toTurnText } = await import(join(PIPELINE_PATH, "to-turn-text.js")));
|
|
279
279
|
({ findDeltaCursor } = await import(join(PIPELINE_PATH, "delta-cursor.js")));
|
|
280
|
-
({
|
|
280
|
+
({ deriveConversationIdentity, deriveMessageContentHash } =
|
|
281
281
|
await import(join(PIPELINE_PATH, "derive-keys.js")));
|
|
282
|
-
({
|
|
282
|
+
({ verifyParticipantElementIds } = await import(join(PIPELINE_PATH, "sender-bind.js")));
|
|
283
283
|
({ getSession } = await import(NEO4J_LIB_PATH));
|
|
284
284
|
({ classifyDocument } = await import(LLM_CLASSIFIER_PATH));
|
|
285
285
|
({ memoryIngest } = await import(MEMORY_INGEST_PATH));
|
|
@@ -316,22 +316,27 @@ async function main() {
|
|
|
316
316
|
log(
|
|
317
317
|
`parsed lines=${normaliserResult.counters.parsed} media-skipped=${normaliserResult.counters.mediaSkipped} system-skipped=${normaliserResult.counters.systemSkipped}`,
|
|
318
318
|
);
|
|
319
|
+
// Task 897: zero matched timestamps means this isn't a chat archive — the
|
|
320
|
+
// file should route through document-ingest instead. The agent's
|
|
321
|
+
// database-operator skill picks the right entry; this LOUD-FAIL surfaces
|
|
322
|
+
// misroute as an actionable signal rather than a silent empty ingest.
|
|
319
323
|
if (allLines.length === 0) {
|
|
320
324
|
cleanup();
|
|
321
|
-
fail("parse", {
|
|
325
|
+
fail("parse", {
|
|
326
|
+
reason: `no timestamp prefixes detected — this archive contains no chat messages with the expected source=${source} grammar; route through document-ingest with mode='document', not conversation-archive-ingest`,
|
|
327
|
+
});
|
|
322
328
|
}
|
|
323
329
|
|
|
324
|
-
// 6c.
|
|
325
|
-
|
|
326
|
-
|
|
330
|
+
// 6c. Verify participant elementIds resolve to graph nodes with the right
|
|
331
|
+
// accountId and labels. Per-line senderName binding is gone (Task 897);
|
|
332
|
+
// operator-confirmed participants attach to the parent :ConversationArchive.
|
|
327
333
|
let session = getSession();
|
|
328
334
|
try {
|
|
329
|
-
await
|
|
335
|
+
await verifyParticipantElementIds({
|
|
330
336
|
session,
|
|
331
337
|
accountId,
|
|
332
338
|
ownerElementId,
|
|
333
339
|
participantElementIds,
|
|
334
|
-
senderNames: distinctSenderNames,
|
|
335
340
|
});
|
|
336
341
|
} catch (err) {
|
|
337
342
|
await session.close().catch(() => {});
|
|
@@ -403,7 +408,8 @@ async function main() {
|
|
|
403
408
|
nextEdgesCreated: 0,
|
|
404
409
|
participantsLinked: 0,
|
|
405
410
|
dateRange: { first: allLines[0].dateSent, last: allLines[allLines.length - 1].dateSent },
|
|
406
|
-
|
|
411
|
+
parsedLineCount: allLines.length,
|
|
412
|
+
sessionsUnenriched: 0,
|
|
407
413
|
topicKeywords: [],
|
|
408
414
|
ms: totalMs,
|
|
409
415
|
priorLastIngestedMessageAt: priorArchive.lastAt,
|
|
@@ -424,9 +430,14 @@ async function main() {
|
|
|
424
430
|
`sessionize source=${source} archiveSha256=${archiveSha256.slice(0, 12)} messages=${deltaLines.length} sessions=${sessions.length} gap-hours=${sessionGapHours}`,
|
|
425
431
|
);
|
|
426
432
|
|
|
427
|
-
// 6g. Classify each session via Haiku (mode='chat')
|
|
433
|
+
// 6g. Classify each session via Haiku (mode='chat'). Task 897: classifier
|
|
434
|
+
// failure on one session does not abort the whole ingest. The session
|
|
435
|
+
// becomes an unenriched raw chunk (timestamps + body, no summary or
|
|
436
|
+
// keywords) and a follow-up pass can re-classify it. One bad Haiku call
|
|
437
|
+
// must not lose 61 good sessions.
|
|
428
438
|
const allChunks = [];
|
|
429
439
|
const allKeywords = new Set();
|
|
440
|
+
let sessionsUnenriched = 0;
|
|
430
441
|
for (const s of sessions) {
|
|
431
442
|
const sessionStart = Date.now();
|
|
432
443
|
const text = toTurnText(s);
|
|
@@ -438,9 +449,28 @@ async function main() {
|
|
|
438
449
|
naturalEdgeMap: "",
|
|
439
450
|
documentText: text,
|
|
440
451
|
});
|
|
441
|
-
if (result.kind === "
|
|
442
|
-
|
|
443
|
-
|
|
452
|
+
if (result.kind === "error") {
|
|
453
|
+
sessionsUnenriched += 1;
|
|
454
|
+
log(`session-unenriched session=${s.index + 1}/${sessions.length} reason="${result.reason.replace(/"/g, '\\"')}"`);
|
|
455
|
+
// Emit one raw :Section:Conversation chunk covering the whole session.
|
|
456
|
+
// No summary, no topicKeywords — a follow-up pass can re-enrich.
|
|
457
|
+
allChunks.push({
|
|
458
|
+
kind: "Conversation",
|
|
459
|
+
title: `Unenriched session ${s.index + 1}`,
|
|
460
|
+
body: text,
|
|
461
|
+
summary: "",
|
|
462
|
+
sourceStart: 0,
|
|
463
|
+
sourceEnd: text.length,
|
|
464
|
+
properties: {
|
|
465
|
+
unenriched: true,
|
|
466
|
+
unenrichedReason: result.reason,
|
|
467
|
+
firstMessageAt: s.firstMessageAt,
|
|
468
|
+
lastMessageAt: s.lastMessageAt,
|
|
469
|
+
messageCount: s.messages.length,
|
|
470
|
+
},
|
|
471
|
+
anchorEdge: null,
|
|
472
|
+
});
|
|
473
|
+
continue;
|
|
444
474
|
}
|
|
445
475
|
const chunkCount = result.output.sections.length;
|
|
446
476
|
log(
|
|
@@ -455,12 +485,14 @@ async function main() {
|
|
|
455
485
|
for (const sec of result.output.sections) allChunks.push(sec);
|
|
456
486
|
for (const kw of result.output.documentKeywords) allKeywords.add(kw);
|
|
457
487
|
}
|
|
488
|
+
if (sessionsUnenriched > 0) {
|
|
489
|
+
log(`classify-summary sessions=${sessions.length} unenriched=${sessionsUnenriched} enriched=${sessions.length - sessionsUnenriched}`);
|
|
490
|
+
}
|
|
458
491
|
|
|
459
492
|
// 6h. Compute lastIngestedMessageHash from the last delta line
|
|
460
493
|
const lastLine = deltaLines[deltaLines.length - 1];
|
|
461
494
|
const lastIngestedMessageHash = deriveMessageContentHash({
|
|
462
495
|
dateSent: lastLine.dateSent,
|
|
463
|
-
senderName: lastLine.senderName,
|
|
464
496
|
body: lastLine.body,
|
|
465
497
|
});
|
|
466
498
|
const lastIngestedMessageAt = lastLine.dateSent;
|
|
@@ -519,23 +551,14 @@ async function main() {
|
|
|
519
551
|
nextEdgesCreated: ingestResult.edgeBreakdown.NEXT ?? 0,
|
|
520
552
|
participantsLinked: ingestResult.edgeBreakdown.PARTICIPANT_IN ?? 0,
|
|
521
553
|
dateRange: { first: allLines[0].dateSent, last: allLines[allLines.length - 1].dateSent },
|
|
522
|
-
|
|
554
|
+
parsedLineCount: allLines.length,
|
|
555
|
+
sessionsUnenriched,
|
|
523
556
|
topicKeywords: Array.from(allKeywords),
|
|
524
557
|
ms: totalMs,
|
|
525
558
|
}) + "\n");
|
|
526
559
|
process.exit(0);
|
|
527
560
|
}
|
|
528
561
|
|
|
529
|
-
function computeSenderHistogram(lines) {
|
|
530
|
-
const counts = new Map();
|
|
531
|
-
for (const l of lines) {
|
|
532
|
-
counts.set(l.senderName, (counts.get(l.senderName) ?? 0) + 1);
|
|
533
|
-
}
|
|
534
|
-
return Array.from(counts.entries())
|
|
535
|
-
.map(([name, count]) => ({ name, count }))
|
|
536
|
-
.sort((a, b) => b.count - a.count);
|
|
537
|
-
}
|
|
538
|
-
|
|
539
562
|
main().catch((err) => {
|
|
540
563
|
fail("uncaught", { reason: err instanceof Error ? err.message : String(err) });
|
|
541
564
|
});
|
package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/timestamp-scanner.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ParsedLine } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Regex contract: must capture date parts in fixed group order. Group 0 is
|
|
4
|
+
* the full prefix match; groups 1..6 are date parts (year, month, day, hour,
|
|
5
|
+
* minute, second). Source normalisers translate their grammar's groups into
|
|
6
|
+
* this fixed shape via the `extractDateParts` callback, so the scanner stays
|
|
7
|
+
* source-agnostic.
|
|
8
|
+
*/
|
|
9
|
+
export interface TimestampPrefixMatch {
|
|
10
|
+
/** Year, four digits (e.g. 2024). */
|
|
11
|
+
year: number;
|
|
12
|
+
/** Month, 1-12. */
|
|
13
|
+
month: number;
|
|
14
|
+
/** Day-of-month, 1-31. */
|
|
15
|
+
day: number;
|
|
16
|
+
/** Hour, 0-23. */
|
|
17
|
+
hour: number;
|
|
18
|
+
/** Minute, 0-59. */
|
|
19
|
+
minute: number;
|
|
20
|
+
/** Second, 0-59. */
|
|
21
|
+
second: number;
|
|
22
|
+
/** Everything on the line after the consumed prefix. */
|
|
23
|
+
remainder: string;
|
|
24
|
+
}
|
|
25
|
+
export type TimestampPrefixMatcher = (line: string) => TimestampPrefixMatch | null;
|
|
26
|
+
export type IsoFormatter = (parts: Omit<TimestampPrefixMatch, "remainder">) => string;
|
|
27
|
+
export interface ScanInput {
|
|
28
|
+
/** Decoded text, lines split by `\n`. */
|
|
29
|
+
text: string;
|
|
30
|
+
/** Returns parsed timestamp + remainder for a matched line, or null. */
|
|
31
|
+
matchPrefix: TimestampPrefixMatcher;
|
|
32
|
+
/** Renders the matched date parts as the canonical ISO `dateSent`. */
|
|
33
|
+
formatIso: IsoFormatter;
|
|
34
|
+
}
|
|
35
|
+
export interface ScanResult {
|
|
36
|
+
parsedLines: ParsedLine[];
|
|
37
|
+
/** Number of lines that matched the timestamp prefix (= parsedLines.length). */
|
|
38
|
+
matchedCount: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Walk `text` line by line. Lines that match `matchPrefix` start a new entry;
|
|
42
|
+
* lines that don't match glue onto the preceding entry's body with `\n`.
|
|
43
|
+
*
|
|
44
|
+
* Returns an empty `parsedLines` array when no line matches the prefix —
|
|
45
|
+
* the caller decides whether to route the input to a non-conversation path
|
|
46
|
+
* (document chunker) or loud-fail.
|
|
47
|
+
*/
|
|
48
|
+
export declare function scanTimestampedLines(input: ScanInput): ScanResult;
|
|
49
|
+
//# sourceMappingURL=timestamp-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timestamp-scanner.d.ts","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/timestamp-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAc7C;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,oBAAoB,GAAG,IAAI,CAAC;AAEnF,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,oBAAoB,EAAE,WAAW,CAAC,KAAK,MAAM,CAAC;AAEtF,MAAM,WAAW,SAAS;IACxB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,WAAW,EAAE,sBAAsB,CAAC;IACpC,sEAAsE;IACtE,SAAS,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,CA8BjE"}
|
package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/timestamp-scanner.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walk `text` line by line. Lines that match `matchPrefix` start a new entry;
|
|
3
|
+
* lines that don't match glue onto the preceding entry's body with `\n`.
|
|
4
|
+
*
|
|
5
|
+
* Returns an empty `parsedLines` array when no line matches the prefix —
|
|
6
|
+
* the caller decides whether to route the input to a non-conversation path
|
|
7
|
+
* (document chunker) or loud-fail.
|
|
8
|
+
*/
|
|
9
|
+
export function scanTimestampedLines(input) {
|
|
10
|
+
const { text, matchPrefix, formatIso } = input;
|
|
11
|
+
const lines = text.split("\n");
|
|
12
|
+
const raw = [];
|
|
13
|
+
for (let i = 0; i < lines.length; i++) {
|
|
14
|
+
const line = lines[i];
|
|
15
|
+
if (line.length === 0 && i === lines.length - 1)
|
|
16
|
+
continue;
|
|
17
|
+
const m = matchPrefix(line);
|
|
18
|
+
if (m) {
|
|
19
|
+
const { remainder, ...parts } = m;
|
|
20
|
+
raw.push({ parts, remainder });
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
const last = raw[raw.length - 1];
|
|
24
|
+
if (last)
|
|
25
|
+
last.remainder += "\n" + line;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const parsedLines = raw.map((r, idx) => ({
|
|
29
|
+
dateSent: formatIso(r.parts),
|
|
30
|
+
body: r.remainder.replace(/\s+$/, ""),
|
|
31
|
+
sequenceIndex: idx,
|
|
32
|
+
}));
|
|
33
|
+
return { parsedLines, matchedCount: parsedLines.length };
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=timestamp-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timestamp-scanner.js","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/timestamp-scanner.ts"],"names":[],"mappings":"AAyDA;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAgB;IACnD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAM/B,MAAM,GAAG,GAAiB,EAAE,CAAC;IAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC1D,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,EAAE,CAAC;YACN,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,GAAG,CAAC,CAAC;YAClC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACjC,IAAI,IAAI;gBAAE,IAAI,CAAC,SAAS,IAAI,IAAI,GAAG,IAAI,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAiB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QACrD,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;QAC5B,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACrC,aAAa,EAAE,GAAG;KACnB,CAAC,CAAC,CAAC;IAEJ,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC;AAC3D,CAAC"}
|
|
@@ -2,18 +2,17 @@ export declare const CONVERSATION_SOURCES: readonly ["whatsapp", "telegram", "si
|
|
|
2
2
|
export type ConversationSource = (typeof CONVERSATION_SOURCES)[number];
|
|
3
3
|
export declare function isConversationSource(s: unknown): s is ConversationSource;
|
|
4
4
|
/**
|
|
5
|
-
* One message after source-specific
|
|
6
|
-
* source
|
|
7
|
-
*
|
|
5
|
+
* One message after source-specific timestamp scanning. Identical shape across
|
|
6
|
+
* every source. Bodies are the raw post-prefix remainder — for WhatsApp this
|
|
7
|
+
* still carries the `Sender: ...` segment; the chat-mode classifier prompt
|
|
8
|
+
* preserves these prefixes verbatim in chunk bodies.
|
|
8
9
|
*/
|
|
9
10
|
export interface ParsedLine {
|
|
10
|
-
/** Sender display name as it appeared in the export (verbatim). */
|
|
11
|
-
senderName: string;
|
|
12
11
|
/** ISO 8601 instant with timezone offset (e.g. "2026-04-30T18:42:00+01:00"). */
|
|
13
12
|
dateSent: string;
|
|
14
|
-
/**
|
|
13
|
+
/** Everything after the timestamp prefix; multi-line continuations glued on `\n`. */
|
|
15
14
|
body: string;
|
|
16
|
-
/** Position within the
|
|
15
|
+
/** Position within the parsed sequence, 0-based. */
|
|
17
16
|
sequenceIndex: number;
|
|
18
17
|
}
|
|
19
18
|
export interface NormaliserCounters {
|
package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/types.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,oBAAoB,sIAUvB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvE,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,kBAAkB,CAExE;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B;qDACiD;IACjD,aAAa,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,kBAAkB,CAAC;CAC9B;AAED,MAAM,MAAM,sBAAsB,GAAG,CACnC,KAAK,EAAE,eAAe,KACnB,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAAC"}
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
// Conversation-archive ingest contracts (Task 894).
|
|
1
|
+
// Conversation-archive ingest contracts (Task 894 / 897).
|
|
2
2
|
//
|
|
3
3
|
// One skill, one writer, one bash entry — source becomes a property on
|
|
4
4
|
// :ConversationArchive and a pluggable normaliser, never a separate skill.
|
|
5
5
|
//
|
|
6
|
+
// Task 897 dropped per-line `senderName`. The normaliser is now a
|
|
7
|
+
// timestamp-prefix scanner — it walks lines, matches a source-specific
|
|
8
|
+
// regex, glues continuations onto the preceding match, and returns body
|
|
9
|
+
// strings verbatim. Bodies are opaque: vCards, system messages, forwarded
|
|
10
|
+
// blocks, and the bare `Sender:` segment all flow through unchanged.
|
|
11
|
+
// Operator-confirmed participants attach to the parent `:ConversationArchive`
|
|
12
|
+
// via `:PARTICIPANT_IN`, never per-message.
|
|
13
|
+
//
|
|
6
14
|
// `ConversationSource` is the closed enum stamped on every :ConversationArchive
|
|
7
15
|
// and :Section:Conversation. Adding a new source = adding a normaliser
|
|
8
16
|
// implementation here + extending this enum, never a new skill or plugin.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/types.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/types.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,EAAE;AACF,uEAAuE;AACvE,2EAA2E;AAC3E,EAAE;AACF,kEAAkE;AAClE,uEAAuE;AACvE,wEAAwE;AACxE,0EAA0E;AAC1E,qEAAqE;AACrE,8EAA8E;AAC9E,4CAA4C;AAC5C,EAAE;AACF,gFAAgF;AAChF,uEAAuE;AACvE,0EAA0E;AAE1E,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,UAAU;IACV,UAAU;IACV,QAAQ;IACR,mBAAmB;IACnB,iBAAiB;IACjB,iBAAiB;IACjB,UAAU;IACV,OAAO;IACP,OAAO;CACC,CAAC;AAIX,MAAM,UAAU,oBAAoB,CAAC,CAAU;IAC7C,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAK,oBAA0C,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC1F,CAAC"}
|
package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/whatsapp-text.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whatsapp-text.d.ts","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/whatsapp-text.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"whatsapp-text.d.ts","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/whatsapp-text.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAiCpE,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,CA+C/E"}
|
package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/whatsapp-text.js
CHANGED
|
@@ -1,34 +1,8 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { basename } from "node:path";
|
|
4
|
+
import { scanTimestampedLines } from "./timestamp-scanner.js";
|
|
4
5
|
const TIMESTAMP_PREFIX = /^\[(\d{2})\/(\d{2})\/(\d{4}|\d{2}),\s+(\d{1,2}):(\d{2})(?::(\d{2}))?\]\s*(.*)$/;
|
|
5
|
-
const LINE_LEVEL_SYSTEM_PATTERNS = [
|
|
6
|
-
/^Messages and calls are end-to-end encrypted/i,
|
|
7
|
-
/'s security code changed\.?$/i,
|
|
8
|
-
/ created group ["“”]/,
|
|
9
|
-
/ added /,
|
|
10
|
-
/ removed /,
|
|
11
|
-
/ left$/,
|
|
12
|
-
/ changed the subject from /,
|
|
13
|
-
/ changed this group's icon/,
|
|
14
|
-
/ joined using this group's invite link/,
|
|
15
|
-
/^You're now an admin$/i,
|
|
16
|
-
/^You created group/i,
|
|
17
|
-
];
|
|
18
|
-
const BODY_LEVEL_SYSTEM_PATTERNS = [
|
|
19
|
-
/^You deleted this message\.?$/,
|
|
20
|
-
/^This message was deleted\.?$/,
|
|
21
|
-
];
|
|
22
|
-
const MEDIA_ONLY_PATTERNS = [
|
|
23
|
-
/^<Media omitted>$/,
|
|
24
|
-
/^IMG-\d+-\w+\.(jpg|jpeg|png|heic|gif)\s*\(file attached\)$/i,
|
|
25
|
-
/^VID-\d+-\w+\.mp4\s*\(file attached\)$/i,
|
|
26
|
-
/^PTT-\d+-\w+\.opus\s*\(file attached\)$/i,
|
|
27
|
-
/^AUD-\d+-\w+\.opus\s*\(file attached\)$/i,
|
|
28
|
-
/^STK-\d+-\w+\.webp\s*\(file attached\)$/i,
|
|
29
|
-
/^.+\.(pdf|docx|doc|xlsx|xls|pptx|ppt|zip|csv|txt)\s*\(file attached\)$/i,
|
|
30
|
-
/^.+attached:\s*.+$/,
|
|
31
|
-
];
|
|
32
6
|
export function whatsappTextNormaliser(input) {
|
|
33
7
|
const { filePath, accountId, timezone } = input;
|
|
34
8
|
const opts = (input.opts ?? {});
|
|
@@ -44,74 +18,29 @@ export function whatsappTextNormaliser(input) {
|
|
|
44
18
|
if (text.length === 0) {
|
|
45
19
|
throw new Error(`whatsapp-text: file is empty — not a _chat.txt. file=${filePath}`);
|
|
46
20
|
}
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
remainder: prefixMatch.remainder,
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
const last = raw[raw.length - 1];
|
|
65
|
-
if (last)
|
|
66
|
-
last.remainder += "\n" + line;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
const parsedLines = [];
|
|
70
|
-
for (const r of raw) {
|
|
71
|
-
const remainder = r.remainder;
|
|
72
|
-
const colonIdx = remainder.indexOf(": ");
|
|
73
|
-
if (colonIdx === -1) {
|
|
74
|
-
const trimmed = remainder.replace(/\s+$/, "");
|
|
75
|
-
if (matchesAny(trimmed, LINE_LEVEL_SYSTEM_PATTERNS)) {
|
|
76
|
-
counters.systemSkipped++;
|
|
77
|
-
continue;
|
|
78
|
-
}
|
|
79
|
-
counters.parseErrors++;
|
|
80
|
-
throw new Error(`whatsapp-text: parse-error file=${filePath} line=${r.rawLineIndex} reason=no-sender-body-separator content="${trimmed.slice(0, 80)}"`);
|
|
81
|
-
}
|
|
82
|
-
const senderName = remainder.slice(0, colonIdx).trim();
|
|
83
|
-
const body = remainder.slice(colonIdx + 2).replace(/\s+$/, "");
|
|
84
|
-
if (body.length === 0) {
|
|
85
|
-
counters.systemSkipped++;
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
if (matchesAny(body, BODY_LEVEL_SYSTEM_PATTERNS)) {
|
|
89
|
-
counters.systemSkipped++;
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
if (matchesAny(body, MEDIA_ONLY_PATTERNS)) {
|
|
93
|
-
counters.mediaSkipped++;
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
const dateSent = isoWithOffset(r.year, r.month, r.day, r.hour, r.minute, r.second, timezone);
|
|
97
|
-
parsedLines.push({
|
|
98
|
-
senderName,
|
|
99
|
-
dateSent,
|
|
100
|
-
body,
|
|
101
|
-
sequenceIndex: parsedLines.length,
|
|
102
|
-
});
|
|
103
|
-
counters.parsed++;
|
|
104
|
-
}
|
|
105
|
-
if (parsedLines.length === 0 && counters.systemSkipped === 0 && counters.mediaSkipped === 0) {
|
|
106
|
-
const sample = sampleFirstNonBlankLine(lines, 100);
|
|
107
|
-
process.stderr.write(`[conversation-archive] parse-grammar-miss source=whatsapp first-line="${sample}"\n`);
|
|
108
|
-
throw new Error(`whatsapp-text: zero parsed lines after walking ${filePath} — not a _chat.txt or all lines failed grammar. parse-grammar-miss first-line="${sample}"`);
|
|
109
|
-
}
|
|
21
|
+
const ordering = resolveOrdering(opts.dateFormat, text);
|
|
22
|
+
const matchPrefix = makeWhatsappPrefixMatcher(ordering);
|
|
23
|
+
const { parsedLines } = scanTimestampedLines({
|
|
24
|
+
text,
|
|
25
|
+
matchPrefix,
|
|
26
|
+
formatIso: (parts) => isoWithOffset(parts.year, parts.month, parts.day, parts.hour, parts.minute, parts.second, timezone),
|
|
27
|
+
});
|
|
28
|
+
// `parsed` is the matched-prefix count (= parsedLines.length).
|
|
29
|
+
// `parseErrors` is structurally zero — the scanner cannot fail on body
|
|
30
|
+
// shape post-Task-897. `systemSkipped` / `mediaSkipped` are zero too:
|
|
31
|
+
// skip detection lived in the pre-897 colon-parser path that's gone.
|
|
32
|
+
// The bin emits `[conversation-archive] parsed lines=N` and routes a
|
|
33
|
+
// zero-parsed file to the document-ingest chunker rather than failing.
|
|
110
34
|
return {
|
|
111
35
|
parsedLines,
|
|
112
36
|
archiveSha256,
|
|
113
37
|
archiveSourceFile: basename(filePath),
|
|
114
|
-
counters
|
|
38
|
+
counters: {
|
|
39
|
+
parsed: parsedLines.length,
|
|
40
|
+
systemSkipped: 0,
|
|
41
|
+
mediaSkipped: 0,
|
|
42
|
+
parseErrors: 0,
|
|
43
|
+
},
|
|
115
44
|
};
|
|
116
45
|
}
|
|
117
46
|
function decodeAndNormalise(bytes) {
|
|
@@ -145,56 +74,45 @@ function decodeAndNormalise(bytes) {
|
|
|
145
74
|
}
|
|
146
75
|
return text;
|
|
147
76
|
}
|
|
148
|
-
function
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
77
|
+
function makeWhatsappPrefixMatcher(ordering) {
|
|
78
|
+
return (line) => {
|
|
79
|
+
const m = line.match(TIMESTAMP_PREFIX);
|
|
80
|
+
if (!m)
|
|
81
|
+
return null;
|
|
82
|
+
const a = parseInt(m[1], 10);
|
|
83
|
+
const b = parseInt(m[2], 10);
|
|
84
|
+
const yearRaw = m[3];
|
|
85
|
+
const hour = parseInt(m[4], 10);
|
|
86
|
+
const minute = parseInt(m[5], 10);
|
|
87
|
+
const second = m[6] !== undefined ? parseInt(m[6], 10) : 0;
|
|
88
|
+
const remainder = m[7] ?? "";
|
|
89
|
+
const day = ordering === "MMDD" ? b : a;
|
|
90
|
+
const month = ordering === "MMDD" ? a : b;
|
|
91
|
+
if (month < 1 || month > 12 || day < 1 || day > 31)
|
|
92
|
+
return null;
|
|
93
|
+
if (hour > 23 || minute > 59 || second > 59)
|
|
94
|
+
return null;
|
|
95
|
+
const year = yearRaw.length === 2 ? 2000 + parseInt(yearRaw, 10) : parseInt(yearRaw, 10);
|
|
96
|
+
return { year, month, day, hour, minute, second, remainder };
|
|
97
|
+
};
|
|
167
98
|
}
|
|
168
|
-
function resolveOrdering(explicit,
|
|
99
|
+
function resolveOrdering(explicit, text) {
|
|
169
100
|
if (explicit === "MM/DD/YY" || explicit === "MM/DD/YYYY")
|
|
170
101
|
return "MMDD";
|
|
171
102
|
if (explicit === "DD/MM/YY" || explicit === "DD/MM/YYYY")
|
|
172
103
|
return "DDMM";
|
|
173
|
-
|
|
174
|
-
|
|
104
|
+
// Probe the file: first valid match wins. DD/MM precedence is consistent
|
|
105
|
+
// with WhatsApp's UK/EU default; explicit MM/DD is an opt-in.
|
|
106
|
+
const ddmm = makeWhatsappPrefixMatcher("DDMM");
|
|
107
|
+
const mmdd = makeWhatsappPrefixMatcher("MMDD");
|
|
108
|
+
for (const line of text.split("\n")) {
|
|
109
|
+
if (ddmm(line))
|
|
175
110
|
return "DDMM";
|
|
176
|
-
if (
|
|
111
|
+
if (mmdd(line))
|
|
177
112
|
return "MMDD";
|
|
178
113
|
}
|
|
179
114
|
return "DDMM";
|
|
180
115
|
}
|
|
181
|
-
function sampleFirstNonBlankLine(lines, maxScan) {
|
|
182
|
-
const scanLimit = Math.min(maxScan, lines.length);
|
|
183
|
-
for (let i = 0; i < scanLimit; i++) {
|
|
184
|
-
const trimmed = lines[i].trim();
|
|
185
|
-
if (trimmed.length === 0)
|
|
186
|
-
continue;
|
|
187
|
-
const sanitised = trimmed.replace(/[\x00-\x1F\x7F]/g, "");
|
|
188
|
-
return sanitised.slice(0, 80);
|
|
189
|
-
}
|
|
190
|
-
return "";
|
|
191
|
-
}
|
|
192
|
-
function matchesAny(text, patterns) {
|
|
193
|
-
for (const p of patterns)
|
|
194
|
-
if (p.test(text))
|
|
195
|
-
return true;
|
|
196
|
-
return false;
|
|
197
|
-
}
|
|
198
116
|
function isoWithOffset(year, month, day, hour, minute, second, timezone) {
|
|
199
117
|
const guessUtcMs = Date.UTC(year, month - 1, day, hour, minute, second);
|
|
200
118
|
let offMin = offsetMinutesAt(new Date(guessUtcMs), timezone);
|
package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/whatsapp-text.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whatsapp-text.js","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/whatsapp-text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"whatsapp-text.js","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/whatsapp-text.ts"],"names":[],"mappings":"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"}
|
package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/delta-cursor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delta-cursor.d.ts","sourceRoot":"","sources":["../../../src/lib/conversation-pipeline/delta-cursor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAqBvE,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAExB,wBAAgB,eAAe,CAC7B,WAAW,EAAE,SAAS,UAAU,EAAE,EAClC,uBAAuB,EAAE,MAAM,GAC9B,YAAY,
|
|
1
|
+
{"version":3,"file":"delta-cursor.d.ts","sourceRoot":"","sources":["../../../src/lib/conversation-pipeline/delta-cursor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAqBvE,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAExB,wBAAgB,eAAe,CAC7B,WAAW,EAAE,SAAS,UAAU,EAAE,EAClC,uBAAuB,EAAE,MAAM,GAC9B,YAAY,CAgBd"}
|
|
@@ -7,7 +7,6 @@ export function findDeltaCursor(parsedLines, lastIngestedMessageHash) {
|
|
|
7
7
|
const line = parsedLines[i];
|
|
8
8
|
const hash = deriveMessageContentHash({
|
|
9
9
|
dateSent: line.dateSent,
|
|
10
|
-
senderName: line.senderName,
|
|
11
10
|
body: line.body,
|
|
12
11
|
});
|
|
13
12
|
if (hash === lastIngestedMessageHash) {
|
package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/delta-cursor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delta-cursor.js","sourceRoot":"","sources":["../../../src/lib/conversation-pipeline/delta-cursor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAyB5D,MAAM,UAAU,eAAe,CAC7B,WAAkC,EAClC,uBAA+B;IAE/B,IAAI,CAAC,uBAAuB,IAAI,CAAC,uBAAuB,CAAC,IAAI,EAAE,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,wBAAwB,CAAC;YACpC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,
|
|
1
|
+
{"version":3,"file":"delta-cursor.js","sourceRoot":"","sources":["../../../src/lib/conversation-pipeline/delta-cursor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAyB5D,MAAM,UAAU,eAAe,CAC7B,WAAkC,EAClC,uBAA+B;IAE/B,IAAI,CAAC,uBAAuB,IAAI,CAAC,uBAAuB,CAAC,IAAI,EAAE,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,wBAAwB,CAAC;YACpC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC,CAAC;QACH,IAAI,IAAI,KAAK,uBAAuB,EAAE,CAAC;YACrC,IAAI,CAAC,KAAK,WAAW,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YAC3D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAC7B,CAAC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export declare function normaliseSenderName(name: string): string;
|
|
2
1
|
export declare function sha256Hex(input: string): string;
|
|
3
2
|
export interface DeriveConversationIdentityInput {
|
|
4
3
|
accountId: string;
|
|
@@ -9,7 +8,6 @@ export interface DeriveConversationIdentityInput {
|
|
|
9
8
|
export declare function deriveConversationIdentity(input: DeriveConversationIdentityInput): string;
|
|
10
9
|
export interface DeriveMessageContentHashInput {
|
|
11
10
|
dateSent: string;
|
|
12
|
-
senderName: string;
|
|
13
11
|
body: string;
|
|
14
12
|
}
|
|
15
13
|
export declare function deriveMessageContentHash(input: DeriveMessageContentHashInput): string;
|
package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/derive-keys.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive-keys.d.ts","sourceRoot":"","sources":["../../../src/lib/conversation-pipeline/derive-keys.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"derive-keys.d.ts","sourceRoot":"","sources":["../../../src/lib/conversation-pipeline/derive-keys.ts"],"names":[],"mappings":"AAuBA,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,MAAM,WAAW,+BAA+B;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB;0DACsD;IACtD,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,+BAA+B,GACrC,MAAM,CASR;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,6BAA6B,GACnC,MAAM,CAER"}
|