memkin 0.4.1 → 0.4.3
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/apply/candidate-selection.d.ts +60 -0
- package/dist/apply/candidate-selection.d.ts.map +1 -0
- package/dist/apply/candidate-selection.js +159 -0
- package/dist/apply/candidate-selection.js.map +1 -0
- package/dist/apply/cutover.d.ts +45 -0
- package/dist/apply/cutover.d.ts.map +1 -0
- package/dist/apply/cutover.js +85 -0
- package/dist/apply/cutover.js.map +1 -0
- package/dist/apply/engine.d.ts +34 -0
- package/dist/apply/engine.d.ts.map +1 -0
- package/dist/apply/engine.js +255 -0
- package/dist/apply/engine.js.map +1 -0
- package/dist/apply/ids.d.ts +9 -0
- package/dist/apply/ids.d.ts.map +1 -0
- package/dist/apply/ids.js +0 -0
- package/dist/apply/ids.js.map +1 -0
- package/dist/apply/page-content.d.ts +14 -0
- package/dist/apply/page-content.d.ts.map +1 -0
- package/dist/apply/page-content.js +0 -0
- package/dist/apply/page-content.js.map +1 -0
- package/dist/apply/rematerialize.d.ts +13 -0
- package/dist/apply/rematerialize.d.ts.map +1 -0
- package/dist/apply/rematerialize.js +150 -0
- package/dist/apply/rematerialize.js.map +1 -0
- package/dist/apply/rollback.d.ts +20 -0
- package/dist/apply/rollback.d.ts.map +1 -0
- package/dist/apply/rollback.js +117 -0
- package/dist/apply/rollback.js.map +1 -0
- package/dist/apply/shadow-runner.d.ts +47 -0
- package/dist/apply/shadow-runner.d.ts.map +1 -0
- package/dist/apply/shadow-runner.js +84 -0
- package/dist/apply/shadow-runner.js.map +1 -0
- package/dist/apply/types.d.ts +51 -0
- package/dist/apply/types.d.ts.map +1 -0
- package/dist/apply/types.js +13 -0
- package/dist/apply/types.js.map +1 -0
- package/dist/cli.js +5 -0
- package/dist/cli.js.map +1 -1
- package/dist/consolidator/consolidator.d.ts +21 -2
- package/dist/consolidator/consolidator.d.ts.map +1 -1
- package/dist/consolidator/consolidator.js +16 -1
- package/dist/consolidator/consolidator.js.map +1 -1
- package/dist/core/config.d.ts +42 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +25 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/pipeline.d.ts +26 -1
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/core/pipeline.js +26 -0
- package/dist/core/pipeline.js.map +1 -1
- package/dist/core/schemas.d.ts +16 -16
- package/dist/daemon/serve-runtime.d.ts +1 -1
- package/dist/daemon/serve-runtime.d.ts.map +1 -1
- package/dist/daemon/serve-runtime.js +26 -1
- package/dist/daemon/serve-runtime.js.map +1 -1
- package/dist/distiller/authority-matrix.d.ts +22 -0
- package/dist/distiller/authority-matrix.d.ts.map +1 -0
- package/dist/distiller/authority-matrix.js +29 -0
- package/dist/distiller/authority-matrix.js.map +1 -0
- package/dist/distiller/contract.d.ts +1427 -0
- package/dist/distiller/contract.d.ts.map +1 -0
- package/dist/distiller/contract.js +166 -0
- package/dist/distiller/contract.js.map +1 -0
- package/dist/distiller/index.d.ts +83 -0
- package/dist/distiller/index.d.ts.map +1 -0
- package/dist/distiller/index.js +226 -0
- package/dist/distiller/index.js.map +1 -0
- package/dist/distiller/map-reduce.d.ts +81 -0
- package/dist/distiller/map-reduce.d.ts.map +1 -0
- package/dist/distiller/map-reduce.js +92 -0
- package/dist/distiller/map-reduce.js.map +1 -0
- package/dist/distiller/msg-id.d.ts +55 -0
- package/dist/distiller/msg-id.d.ts.map +1 -0
- package/dist/distiller/msg-id.js +91 -0
- package/dist/distiller/msg-id.js.map +1 -0
- package/dist/distiller/payload-privacy.d.ts +18 -0
- package/dist/distiller/payload-privacy.d.ts.map +1 -0
- package/dist/distiller/payload-privacy.js +51 -0
- package/dist/distiller/payload-privacy.js.map +1 -0
- package/dist/distiller/prompt.d.ts +28 -0
- package/dist/distiller/prompt.d.ts.map +1 -0
- package/dist/distiller/prompt.js +69 -0
- package/dist/distiller/prompt.js.map +1 -0
- package/dist/distiller/raw-privacy.d.ts +55 -0
- package/dist/distiller/raw-privacy.d.ts.map +1 -0
- package/dist/distiller/raw-privacy.js +123 -0
- package/dist/distiller/raw-privacy.js.map +1 -0
- package/dist/distiller/segmenter.d.ts +40 -0
- package/dist/distiller/segmenter.d.ts.map +1 -0
- package/dist/distiller/segmenter.js +75 -0
- package/dist/distiller/segmenter.js.map +1 -0
- package/dist/embedded-assets.generated.d.ts.map +1 -1
- package/dist/embedded-assets.generated.js +5 -4
- package/dist/embedded-assets.generated.js.map +1 -1
- package/dist/eval/golden.d.ts +12 -12
- package/dist/server/api.d.ts.map +1 -1
- package/dist/server/api.js +6 -1
- package/dist/server/api.js.map +1 -1
- package/dist/setup/generate-config.d.ts.map +1 -1
- package/dist/setup/generate-config.js +3 -0
- package/dist/setup/generate-config.js.map +1 -1
- package/dist/setup/validate-config.d.ts +2 -1
- package/dist/setup/validate-config.d.ts.map +1 -1
- package/dist/setup/validate-config.js.map +1 -1
- package/dist/store/agent-sessions.d.ts.map +1 -1
- package/dist/store/agent-sessions.js +3 -1
- package/dist/store/agent-sessions.js.map +1 -1
- package/dist/store/distilled-payload.d.ts +50 -0
- package/dist/store/distilled-payload.d.ts.map +1 -0
- package/dist/store/distilled-payload.js +117 -0
- package/dist/store/distilled-payload.js.map +1 -0
- package/dist/store/engine-factory.d.ts.map +1 -1
- package/dist/store/engine-factory.js +8 -1
- package/dist/store/engine-factory.js.map +1 -1
- package/dist/store/migrations/index.d.ts.map +1 -1
- package/dist/store/migrations/index.js +139 -0
- package/dist/store/migrations/index.js.map +1 -1
- package/dist/store/search.d.ts.map +1 -1
- package/dist/store/search.js +15 -8
- package/dist/store/search.js.map +1 -1
- package/dist/store/source-filter.d.ts +19 -0
- package/dist/store/source-filter.d.ts.map +1 -0
- package/dist/store/source-filter.js +44 -0
- package/dist/store/source-filter.js.map +1 -0
- package/dist/store/timeline.d.ts.map +1 -1
- package/dist/store/timeline.js +15 -8
- package/dist/store/timeline.js.map +1 -1
- package/dist/synth/scope.d.ts.map +1 -1
- package/dist/synth/scope.js +10 -4
- package/dist/synth/scope.js.map +1 -1
- package/package.json +3 -2
- package/web/dist/assets/index-Cie2dVF3.js +5167 -0
- package/web/dist/assets/index-diZtO98v.css +2 -0
- package/web/dist/assets/newsreader-T5L87s1n.woff2 +0 -0
- package/web/dist/index.html +19 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sequential map-reduce distillation (spec §5.1).
|
|
3
|
+
*
|
|
4
|
+
* MAP (sequential, not parallel): each segment is distilled in order; the prompt
|
|
5
|
+
* for segment N carries forward segment N-1's `carry_forward` (in-progress topics
|
|
6
|
+
* / undecided items) so `overturned` can be filled reliably. Session counts are
|
|
7
|
+
* low, so sequential cost is acceptable.
|
|
8
|
+
*
|
|
9
|
+
* Intermediate per-segment schema:
|
|
10
|
+
* { seg_no, summary, tentative_signals[], overturned[], carry_forward }
|
|
11
|
+
*
|
|
12
|
+
* REDUCE: merges the tentative signals into a final payload. The reduce prompt
|
|
13
|
+
* carries the explicit rule "conclusions appearing in any `overturned` must not
|
|
14
|
+
* enter the final signals". We additionally post-filter overturned topics
|
|
15
|
+
* programmatically so a model slip cannot leak a retracted conclusion back in.
|
|
16
|
+
*
|
|
17
|
+
* The final payload is only structurally validated here (parsePayload). Evidence
|
|
18
|
+
* bounds + reference.url locatability (msg-id.ts) and second-pass privacy run in
|
|
19
|
+
* the orchestrator, which has the full transcript.
|
|
20
|
+
*/
|
|
21
|
+
import { z } from "zod";
|
|
22
|
+
import { DistilledPayloadSchema, parsePayload, slugifyTopic, } from "./contract.js";
|
|
23
|
+
import { getMapPrompt, getReducePrompt } from "./prompt.js";
|
|
24
|
+
// Intermediate map output. tentative_signals / overturned stay loose (z.unknown /
|
|
25
|
+
// partial) because a segment view is provisional — only the reduced payload is
|
|
26
|
+
// held to the strict contract.
|
|
27
|
+
export const OverturnedSchema = z.object({
|
|
28
|
+
topic: z.string().min(1),
|
|
29
|
+
reason: z.string().optional(),
|
|
30
|
+
});
|
|
31
|
+
export const SegmentSummarySchema = z.object({
|
|
32
|
+
seg_no: z.number(),
|
|
33
|
+
summary: z.string(),
|
|
34
|
+
tentative_signals: z.array(z.record(z.unknown())),
|
|
35
|
+
overturned: z.array(OverturnedSchema),
|
|
36
|
+
carry_forward: z.string(),
|
|
37
|
+
});
|
|
38
|
+
function renderSegment(seg) {
|
|
39
|
+
return seg.messages
|
|
40
|
+
.map((m) => {
|
|
41
|
+
const cont = m.continued ? " (continued)" : "";
|
|
42
|
+
return `[${m.msgId}${cont}] ${m.role}: ${m.content}`;
|
|
43
|
+
})
|
|
44
|
+
.join("\n");
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Run sequential map over segments then a single reduce.
|
|
48
|
+
* `criteria` is the judgment-declaration prompt fragment (spec §5 / §11 task 2.9);
|
|
49
|
+
* callers inject the embedded distill criteria.
|
|
50
|
+
*/
|
|
51
|
+
export async function mapReduceDistill(segments, provider, criteria) {
|
|
52
|
+
const summaries = [];
|
|
53
|
+
let carry = "";
|
|
54
|
+
for (const seg of segments) {
|
|
55
|
+
const prompt = getMapPrompt({
|
|
56
|
+
criteria,
|
|
57
|
+
segmentText: renderSegment(seg),
|
|
58
|
+
segNo: seg.segNo,
|
|
59
|
+
carryForward: carry,
|
|
60
|
+
});
|
|
61
|
+
const raw = await provider.chat([
|
|
62
|
+
{ role: "system", content: "You are a session distiller. Reply with JSON only." },
|
|
63
|
+
{ role: "user", content: prompt },
|
|
64
|
+
], { responseFormat: "json" });
|
|
65
|
+
const parsed = SegmentSummarySchema.parse(JSON.parse(raw));
|
|
66
|
+
summaries.push(parsed);
|
|
67
|
+
carry = parsed.carry_forward;
|
|
68
|
+
}
|
|
69
|
+
const overturnedTopics = summaries.flatMap((s) => s.overturned.map((o) => o.topic));
|
|
70
|
+
const overturnedSlugs = new Set(overturnedTopics.map(slugifyTopic));
|
|
71
|
+
const reducePrompt = getReducePrompt({
|
|
72
|
+
criteria,
|
|
73
|
+
segmentSummaries: summaries,
|
|
74
|
+
overturnedTopics,
|
|
75
|
+
});
|
|
76
|
+
const reduceRaw = await provider.chat([
|
|
77
|
+
{ role: "system", content: "You are a session distiller. Reply with JSON only." },
|
|
78
|
+
{ role: "user", content: reducePrompt },
|
|
79
|
+
], { responseFormat: "json" });
|
|
80
|
+
const reduceParsed = DistilledPayloadSchema.parse(JSON.parse(reduceRaw));
|
|
81
|
+
// Belt-and-suspenders: strip any signal whose topic was overturned, even if the
|
|
82
|
+
// reducer wrongly re-included it.
|
|
83
|
+
const filtered = {
|
|
84
|
+
signals: reduceParsed.signals.filter((s) => !overturnedSlugs.has(slugifyTopic(s.topic))),
|
|
85
|
+
};
|
|
86
|
+
const finalRes = parsePayload(filtered);
|
|
87
|
+
if (!finalRes.ok) {
|
|
88
|
+
throw new Error(`reduced payload failed validation: ${finalRes.error.message}`);
|
|
89
|
+
}
|
|
90
|
+
return { payload: finalRes.payload, overturnedTopics, segmentSummaries: summaries };
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=map-reduce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"map-reduce.js","sourceRoot":"","sources":["../../src/distiller/map-reduce.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Programmatic msg_id assignment + evidence validation (spec §5.2).
|
|
3
|
+
*
|
|
4
|
+
* The pipeline — not the model — assigns each transcript message a sequential
|
|
5
|
+
* `msg_id` (`msg-1`, `msg-2`, …). Oversized messages get sub-segment ids with a
|
|
6
|
+
* dotted suffix (`msg-42.1`, `msg-42.2`; see segmenter.ts). The model may only
|
|
7
|
+
* cite these given ids, and the validation layer here rejects any evidence range
|
|
8
|
+
* that falls outside the assigned set — killing line-number / id hallucination.
|
|
9
|
+
*
|
|
10
|
+
* It also enforces the spec §5 rule that `reference.url` must be locatable inside
|
|
11
|
+
* the text of its own evidence range: we pull the evidence text and check the url
|
|
12
|
+
* appears as a substring, so the model cannot conjure a url out of thin air.
|
|
13
|
+
*
|
|
14
|
+
* Ordering note: ranges are resolved by INDEX into the ordered message list, not
|
|
15
|
+
* by parsing the numeric id. This makes plain ids and dotted sub-segment ids
|
|
16
|
+
* (`msg-42.1`) order uniformly without a bespoke comparator.
|
|
17
|
+
*/
|
|
18
|
+
import type { DistilledSignal } from "./contract.js";
|
|
19
|
+
export type MessageRole = "user" | "assistant";
|
|
20
|
+
export interface RawInputMessage {
|
|
21
|
+
role: MessageRole;
|
|
22
|
+
content: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ParsedMessage {
|
|
25
|
+
msgId: string;
|
|
26
|
+
role: MessageRole;
|
|
27
|
+
content: string;
|
|
28
|
+
}
|
|
29
|
+
/** Assign sequential `msg-N` ids to messages in order. */
|
|
30
|
+
export declare function assignMsgIds(messages: RawInputMessage[]): ParsedMessage[];
|
|
31
|
+
interface EvidenceRange {
|
|
32
|
+
start: string;
|
|
33
|
+
end: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Concatenate the text of every message in [start, end] (inclusive), resolved by
|
|
37
|
+
* index. Throws if either bound is unknown or the range is inverted — callers
|
|
38
|
+
* that want a boolean should go through validateEvidence.
|
|
39
|
+
*/
|
|
40
|
+
export declare function collectEvidenceText(parsed: ParsedMessage[], range: EvidenceRange): string;
|
|
41
|
+
export type ValidateEvidenceResult = {
|
|
42
|
+
ok: true;
|
|
43
|
+
} | {
|
|
44
|
+
ok: false;
|
|
45
|
+
errors: string[];
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Validate every signal's evidence against the assigned msg_id set:
|
|
49
|
+
* - both bounds must reference an assigned id;
|
|
50
|
+
* - the range must not be inverted;
|
|
51
|
+
* - for `reference` signals, the url must appear in the evidence text.
|
|
52
|
+
*/
|
|
53
|
+
export declare function validateEvidence(signals: DistilledSignal[], parsed: ParsedMessage[]): ValidateEvidenceResult;
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=msg-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-id.d.ts","sourceRoot":"","sources":["../../src/distiller/msg-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,CAAC;AAE/C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,aAAa,EAAE,CAMzE;AAED,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAMD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAUzF;AAED,MAAM,MAAM,sBAAsB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEpF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,eAAe,EAAE,EAC1B,MAAM,EAAE,aAAa,EAAE,GACtB,sBAAsB,CAwCxB"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Programmatic msg_id assignment + evidence validation (spec §5.2).
|
|
3
|
+
*
|
|
4
|
+
* The pipeline — not the model — assigns each transcript message a sequential
|
|
5
|
+
* `msg_id` (`msg-1`, `msg-2`, …). Oversized messages get sub-segment ids with a
|
|
6
|
+
* dotted suffix (`msg-42.1`, `msg-42.2`; see segmenter.ts). The model may only
|
|
7
|
+
* cite these given ids, and the validation layer here rejects any evidence range
|
|
8
|
+
* that falls outside the assigned set — killing line-number / id hallucination.
|
|
9
|
+
*
|
|
10
|
+
* It also enforces the spec §5 rule that `reference.url` must be locatable inside
|
|
11
|
+
* the text of its own evidence range: we pull the evidence text and check the url
|
|
12
|
+
* appears as a substring, so the model cannot conjure a url out of thin air.
|
|
13
|
+
*
|
|
14
|
+
* Ordering note: ranges are resolved by INDEX into the ordered message list, not
|
|
15
|
+
* by parsing the numeric id. This makes plain ids and dotted sub-segment ids
|
|
16
|
+
* (`msg-42.1`) order uniformly without a bespoke comparator.
|
|
17
|
+
*/
|
|
18
|
+
/** Assign sequential `msg-N` ids to messages in order. */
|
|
19
|
+
export function assignMsgIds(messages) {
|
|
20
|
+
return messages.map((m, i) => ({
|
|
21
|
+
msgId: `msg-${i + 1}`,
|
|
22
|
+
role: m.role,
|
|
23
|
+
content: m.content,
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
function indexOfMsgId(parsed, msgId) {
|
|
27
|
+
return parsed.findIndex((m) => m.msgId === msgId);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Concatenate the text of every message in [start, end] (inclusive), resolved by
|
|
31
|
+
* index. Throws if either bound is unknown or the range is inverted — callers
|
|
32
|
+
* that want a boolean should go through validateEvidence.
|
|
33
|
+
*/
|
|
34
|
+
export function collectEvidenceText(parsed, range) {
|
|
35
|
+
const s = indexOfMsgId(parsed, range.start);
|
|
36
|
+
const e = indexOfMsgId(parsed, range.end);
|
|
37
|
+
if (s < 0)
|
|
38
|
+
throw new Error(`unknown evidence start id: ${range.start}`);
|
|
39
|
+
if (e < 0)
|
|
40
|
+
throw new Error(`unknown evidence end id: ${range.end}`);
|
|
41
|
+
if (s > e)
|
|
42
|
+
throw new Error(`inverted evidence range: ${range.start}..${range.end}`);
|
|
43
|
+
return parsed
|
|
44
|
+
.slice(s, e + 1)
|
|
45
|
+
.map((m) => m.content)
|
|
46
|
+
.join("\n");
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Validate every signal's evidence against the assigned msg_id set:
|
|
50
|
+
* - both bounds must reference an assigned id;
|
|
51
|
+
* - the range must not be inverted;
|
|
52
|
+
* - for `reference` signals, the url must appear in the evidence text.
|
|
53
|
+
*/
|
|
54
|
+
export function validateEvidence(signals, parsed) {
|
|
55
|
+
const errors = [];
|
|
56
|
+
for (const sig of signals) {
|
|
57
|
+
for (const range of sig.evidence) {
|
|
58
|
+
const s = indexOfMsgId(parsed, range.start);
|
|
59
|
+
const e = indexOfMsgId(parsed, range.end);
|
|
60
|
+
if (s < 0) {
|
|
61
|
+
errors.push(`signal "${sig.topic}": evidence start "${range.start}" is out of bounds`);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (e < 0) {
|
|
65
|
+
errors.push(`signal "${sig.topic}": evidence end "${range.end}" is out of bounds`);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (s > e) {
|
|
69
|
+
errors.push(`signal "${sig.topic}": inverted evidence range ${range.start}..${range.end}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (sig.type === "reference") {
|
|
73
|
+
const found = sig.evidence.some((range) => {
|
|
74
|
+
const s = indexOfMsgId(parsed, range.start);
|
|
75
|
+
const e = indexOfMsgId(parsed, range.end);
|
|
76
|
+
if (s < 0 || e < 0 || s > e)
|
|
77
|
+
return false;
|
|
78
|
+
const text = parsed
|
|
79
|
+
.slice(s, e + 1)
|
|
80
|
+
.map((m) => m.content)
|
|
81
|
+
.join("\n");
|
|
82
|
+
return text.includes(sig.url);
|
|
83
|
+
});
|
|
84
|
+
if (!found) {
|
|
85
|
+
errors.push(`signal "${sig.topic}": reference.url "${sig.url}" not found in its evidence text (possible hallucination)`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return errors.length === 0 ? { ok: true } : { ok: false, errors };
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=msg-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-id.js","sourceRoot":"","sources":["../../src/distiller/msg-id.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Second-pass privacy over the structured distilled payload (spec §4.3).
|
|
3
|
+
*
|
|
4
|
+
* The first pass (RawMessagePrivacyProcessor) redacts raw message text before
|
|
5
|
+
* the LLM sees it; this second pass runs right before the payload is written to
|
|
6
|
+
* the outbox, catching sensitive strings the model might have reproduced or
|
|
7
|
+
* synthesized in its OUTPUT (e.g. reassembling a phone number from context).
|
|
8
|
+
*
|
|
9
|
+
* Field policy mirrors PrivacyProcessor (privacy.ts): free-text narrative fields
|
|
10
|
+
* are redacted; structural fields (type, authority, status, evidence, dates,
|
|
11
|
+
* enums), entity NAMES (aligned with Entity.name never being redacted) and
|
|
12
|
+
* reference urls (the url is the core field, checked against evidence) are left
|
|
13
|
+
* intact.
|
|
14
|
+
*/
|
|
15
|
+
import type { PrivacyConfig } from "../core/config.js";
|
|
16
|
+
import type { DistilledPayload } from "./contract.js";
|
|
17
|
+
export declare function redactPayload(payload: DistilledPayload, config: PrivacyConfig): DistilledPayload;
|
|
18
|
+
//# sourceMappingURL=payload-privacy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload-privacy.d.ts","sourceRoot":"","sources":["../../src/distiller/payload-privacy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAmB,MAAM,eAAe,CAAC;AAGvE,wBAAgB,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,aAAa,GAAG,gBAAgB,CAoChG"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Second-pass privacy over the structured distilled payload (spec §4.3).
|
|
3
|
+
*
|
|
4
|
+
* The first pass (RawMessagePrivacyProcessor) redacts raw message text before
|
|
5
|
+
* the LLM sees it; this second pass runs right before the payload is written to
|
|
6
|
+
* the outbox, catching sensitive strings the model might have reproduced or
|
|
7
|
+
* synthesized in its OUTPUT (e.g. reassembling a phone number from context).
|
|
8
|
+
*
|
|
9
|
+
* Field policy mirrors PrivacyProcessor (privacy.ts): free-text narrative fields
|
|
10
|
+
* are redacted; structural fields (type, authority, status, evidence, dates,
|
|
11
|
+
* enums), entity NAMES (aligned with Entity.name never being redacted) and
|
|
12
|
+
* reference urls (the url is the core field, checked against evidence) are left
|
|
13
|
+
* intact.
|
|
14
|
+
*/
|
|
15
|
+
import { RawMessagePrivacyProcessor } from "./raw-privacy.js";
|
|
16
|
+
export function redactPayload(payload, config) {
|
|
17
|
+
if (!config.enabled)
|
|
18
|
+
return payload;
|
|
19
|
+
// Force irreversible for the structured pass: the reversible restoration map
|
|
20
|
+
// is only kept for raw message text keyed by msg_id (first pass); structured
|
|
21
|
+
// output redactions are not reversible (nothing to anchor them to).
|
|
22
|
+
const proc = new RawMessagePrivacyProcessor({ ...config, mode: "irreversible" });
|
|
23
|
+
const r = (text) => proc.redactString(text);
|
|
24
|
+
const rOpt = (text) => (text === undefined ? undefined : r(text));
|
|
25
|
+
const redactSignal = (sig) => {
|
|
26
|
+
const common = {
|
|
27
|
+
topic: r(sig.topic),
|
|
28
|
+
what: r(sig.what),
|
|
29
|
+
why: rOpt(sig.why),
|
|
30
|
+
project: sig.project,
|
|
31
|
+
entities: sig.entities,
|
|
32
|
+
authority: sig.authority,
|
|
33
|
+
supersedes_topic: rOpt(sig.supersedes_topic),
|
|
34
|
+
evidence: sig.evidence,
|
|
35
|
+
persistence_reason: r(sig.persistence_reason),
|
|
36
|
+
};
|
|
37
|
+
switch (sig.type) {
|
|
38
|
+
case "task":
|
|
39
|
+
return { ...sig, ...common, owner: rOpt(sig.owner) };
|
|
40
|
+
case "reference":
|
|
41
|
+
return { ...sig, ...common, trigger: rOpt(sig.trigger) };
|
|
42
|
+
case "preference":
|
|
43
|
+
return { ...sig, ...common, subject: r(sig.subject) };
|
|
44
|
+
default:
|
|
45
|
+
// decision / knowledge / discovery carry no extra free-text fields.
|
|
46
|
+
return { ...sig, ...common };
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
return { signals: payload.signals.map(redactSignal) };
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=payload-privacy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload-privacy.js","sourceRoot":"","sources":["../../src/distiller/payload-privacy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAE9D,MAAM,UAAU,aAAa,CAAC,OAAyB,EAAE,MAAqB;IAC5E,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC;IAEpC,6EAA6E;IAC7E,6EAA6E;IAC7E,oEAAoE;IACpE,MAAM,IAAI,GAAG,IAAI,0BAA0B,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;IACjF,MAAM,CAAC,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,CAAC,IAAwB,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEtF,MAAM,YAAY,GAAG,CAAC,GAAoB,EAAmB,EAAE;QAC7D,MAAM,MAAM,GAAG;YACb,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;YACnB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;YACjB,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAClB,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC;YAC5C,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,kBAAkB,EAAE,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC;SAC9C,CAAC;QACF,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,MAAM;gBACT,OAAO,EAAE,GAAG,GAAG,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACvD,KAAK,WAAW;gBACd,OAAO,EAAE,GAAG,GAAG,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3D,KAAK,YAAY;gBACf,OAAO,EAAE,GAAG,GAAG,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACxD;gBACE,oEAAoE;gBACpE,OAAO,EAAE,GAAG,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC;QACjC,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Distillation prompt assembly (spec §5, §5.1, §11 task 2.9).
|
|
3
|
+
*
|
|
4
|
+
* The judgment-declaration criteria live in an embedded markdown prompt
|
|
5
|
+
* (`src/extractors/prompts/distill.md`, inlined by gen:assets into PROMPTS).
|
|
6
|
+
* This module wraps that criteria into the concrete map + reduce prompts, with
|
|
7
|
+
* carry-forward and overturned instructions threaded in.
|
|
8
|
+
*
|
|
9
|
+
* Keeping prompt text out of map-reduce.ts lets the criteria be iterated
|
|
10
|
+
* (PR-1 eval loop) without touching orchestration logic.
|
|
11
|
+
*/
|
|
12
|
+
import type { SegmentSummary } from "./map-reduce.js";
|
|
13
|
+
/** Load the embedded distill criteria; falls back to a terse built-in if absent. */
|
|
14
|
+
export declare function getDistillCriteria(): string;
|
|
15
|
+
export interface MapPromptInput {
|
|
16
|
+
criteria?: string;
|
|
17
|
+
segmentText: string;
|
|
18
|
+
segNo: number;
|
|
19
|
+
carryForward: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function getMapPrompt(input: MapPromptInput): string;
|
|
22
|
+
export interface ReducePromptInput {
|
|
23
|
+
criteria?: string;
|
|
24
|
+
segmentSummaries: SegmentSummary[];
|
|
25
|
+
overturnedTopics: string[];
|
|
26
|
+
}
|
|
27
|
+
export declare function getReducePrompt(input: ReducePromptInput): string;
|
|
28
|
+
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/distiller/prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,oFAAoF;AACpF,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAQD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAwB1D;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,cAAc,EAAE,CAAC;IACnC,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAuBhE"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Distillation prompt assembly (spec §5, §5.1, §11 task 2.9).
|
|
3
|
+
*
|
|
4
|
+
* The judgment-declaration criteria live in an embedded markdown prompt
|
|
5
|
+
* (`src/extractors/prompts/distill.md`, inlined by gen:assets into PROMPTS).
|
|
6
|
+
* This module wraps that criteria into the concrete map + reduce prompts, with
|
|
7
|
+
* carry-forward and overturned instructions threaded in.
|
|
8
|
+
*
|
|
9
|
+
* Keeping prompt text out of map-reduce.ts lets the criteria be iterated
|
|
10
|
+
* (PR-1 eval loop) without touching orchestration logic.
|
|
11
|
+
*/
|
|
12
|
+
import { PROMPTS } from "../embedded-assets.generated.js";
|
|
13
|
+
/** Load the embedded distill criteria; falls back to a terse built-in if absent. */
|
|
14
|
+
export function getDistillCriteria() {
|
|
15
|
+
return PROMPTS["distill.md"] ?? FALLBACK_CRITERIA;
|
|
16
|
+
}
|
|
17
|
+
const FALLBACK_CRITERIA = `You are distilling an agent session for a future retriever 30 days from now.
|
|
18
|
+
Record only what a colleague would need to reconstruct WHY things are the way they
|
|
19
|
+
are. Distinguish: the user deciding (user_confirmed) vs. you proposing
|
|
20
|
+
(assistant_proposed) vs. a claim proven by a tool result (assistant_claimed).
|
|
21
|
+
Skip transient debugging chatter and unconfirmed proposals.`;
|
|
22
|
+
export function getMapPrompt(input) {
|
|
23
|
+
const criteria = input.criteria ?? getDistillCriteria();
|
|
24
|
+
const carrySection = input.carryForward.trim().length > 0
|
|
25
|
+
? `\n## Carried forward from the previous segment\n\n${input.carryForward}\n`
|
|
26
|
+
: "";
|
|
27
|
+
return `${criteria}
|
|
28
|
+
|
|
29
|
+
## Segment ${input.segNo}
|
|
30
|
+
${carrySection}
|
|
31
|
+
## Messages
|
|
32
|
+
|
|
33
|
+
${input.segmentText}
|
|
34
|
+
|
|
35
|
+
## Instructions
|
|
36
|
+
|
|
37
|
+
Distill THIS segment only. Output ONLY JSON of shape:
|
|
38
|
+
{
|
|
39
|
+
"seg_no": ${input.segNo},
|
|
40
|
+
"summary": "<one-paragraph gist of this segment>",
|
|
41
|
+
"tentative_signals": [ /* candidate signals per the contract */ ],
|
|
42
|
+
"overturned": [ { "topic": "<a topic from earlier that is now retracted>", "reason": "..." } ],
|
|
43
|
+
"carry_forward": "<in-progress topics / undecided items to hand to the next segment>"
|
|
44
|
+
}`;
|
|
45
|
+
}
|
|
46
|
+
export function getReducePrompt(input) {
|
|
47
|
+
const criteria = input.criteria ?? getDistillCriteria();
|
|
48
|
+
const summariesJson = JSON.stringify(input.segmentSummaries, null, 2);
|
|
49
|
+
const overturnedList = input.overturnedTopics.length > 0
|
|
50
|
+
? input.overturnedTopics.map((t) => `- ${t}`).join("\n")
|
|
51
|
+
: "(none)";
|
|
52
|
+
return `${criteria}
|
|
53
|
+
|
|
54
|
+
## Segment summaries
|
|
55
|
+
|
|
56
|
+
${summariesJson}
|
|
57
|
+
|
|
58
|
+
## Overturned topics (MUST NOT appear in the final signals)
|
|
59
|
+
|
|
60
|
+
${overturnedList}
|
|
61
|
+
|
|
62
|
+
## Instructions
|
|
63
|
+
|
|
64
|
+
Merge the tentative signals across all segments into the final session payload.
|
|
65
|
+
RULE: any conclusion that appears in the overturned list above MUST NOT enter the
|
|
66
|
+
final signals. Deduplicate: no two final signals may share the same (type, topic).
|
|
67
|
+
Output ONLY JSON of shape { "signals": [ ...signals per the contract... ] }.`;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/distiller/prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAG1D,oFAAoF;AACpF,MAAM,UAAU,kBAAkB;IAChC,OAAO,OAAO,CAAC,YAAY,CAAC,IAAI,iBAAiB,CAAC;AACpD,CAAC;AAED,MAAM,iBAAiB,GAAG;;;;4DAIkC,CAAC;AAS7D,MAAM,UAAU,YAAY,CAAC,KAAqB;IAChD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,kBAAkB,EAAE,CAAC;IACxD,MAAM,YAAY,GAChB,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;QAClC,CAAC,CAAC,qDAAqD,KAAK,CAAC,YAAY,IAAI;QAC7E,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,GAAG,QAAQ;;aAEP,KAAK,CAAC,KAAK;EACtB,YAAY;;;EAGZ,KAAK,CAAC,WAAW;;;;;;cAML,KAAK,CAAC,KAAK;;;;;EAKvB,CAAC;AACH,CAAC;AAQD,MAAM,UAAU,eAAe,CAAC,KAAwB;IACtD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,kBAAkB,EAAE,CAAC;IACxD,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACtE,MAAM,cAAc,GAClB,KAAK,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC;QAC/B,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACxD,CAAC,CAAC,QAAQ,CAAC;IACf,OAAO,GAAG,QAAQ;;;;EAIlB,aAAa;;;;EAIb,cAAc;;;;;;;6EAO6D,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RawMessagePrivacyProcessor — pre-LLM redaction (spec §4.3, first pass).
|
|
3
|
+
*
|
|
4
|
+
* The legacy block pipeline sends raw messages to the LLM and only redacts the
|
|
5
|
+
* structured ExtractionResult afterwards (privacy.ts / PrivacyProcessor) — so
|
|
6
|
+
* the model sees un-redacted originals. For the distiller we fix that ordering:
|
|
7
|
+
* this processor redacts raw message TEXT before it is ever handed to the LLM
|
|
8
|
+
* (every map/reduce segment input goes through it first).
|
|
9
|
+
*
|
|
10
|
+
* It reuses the exact PrivacyConfig rules and patterns as PrivacyProcessor, but
|
|
11
|
+
* operates on plain strings keyed by msg_id (not on ExtractionResult). In
|
|
12
|
+
* reversible mode the restoration map is grouped by msg_id (spec §4.3) so an
|
|
13
|
+
* authorized reader can recover the original text for a cited evidence range.
|
|
14
|
+
*/
|
|
15
|
+
import type { PrivacyConfig } from "../core/config.js";
|
|
16
|
+
import type { ParsedMessage } from "./msg-id.js";
|
|
17
|
+
/** A single reversible redaction: what was replaced, with what, and where. */
|
|
18
|
+
export interface RawRedactionEntry {
|
|
19
|
+
original: string;
|
|
20
|
+
replacement: string;
|
|
21
|
+
/** Character offset in the redacted string (post-substitution). */
|
|
22
|
+
position: number;
|
|
23
|
+
}
|
|
24
|
+
/** Restoration map: msg_id → the redactions applied to that message. */
|
|
25
|
+
export type RestorationMap = Record<string, RawRedactionEntry[]>;
|
|
26
|
+
export interface RedactMessagesResult {
|
|
27
|
+
messages: ParsedMessage[];
|
|
28
|
+
restorationMap: RestorationMap;
|
|
29
|
+
}
|
|
30
|
+
export declare class RawMessagePrivacyProcessor {
|
|
31
|
+
private readonly config;
|
|
32
|
+
constructor(config: PrivacyConfig);
|
|
33
|
+
private patterns;
|
|
34
|
+
private escapeRegex;
|
|
35
|
+
/**
|
|
36
|
+
* Redact one message's text. Returns the redacted string and (in reversible
|
|
37
|
+
* mode) the ordered redaction entries.
|
|
38
|
+
*/
|
|
39
|
+
private redactText;
|
|
40
|
+
/**
|
|
41
|
+
* Redact a single free-text string (no restoration tracking exposed).
|
|
42
|
+
* Used by the second-pass payload privacy (payload-privacy.ts).
|
|
43
|
+
*/
|
|
44
|
+
redactString(text: string): string;
|
|
45
|
+
/** Redact every message's text before it is sent to the LLM. */
|
|
46
|
+
redactMessages(messages: ParsedMessage[]): RedactMessagesResult;
|
|
47
|
+
/**
|
|
48
|
+
* Reverse redaction for a single message's (redacted) text using its
|
|
49
|
+
* msg_id-keyed entries. Applies entries in forward order (they were recorded
|
|
50
|
+
* against post-substitution offsets in reverse, so left-to-right restore is
|
|
51
|
+
* position-stable because each restore preserves earlier offsets).
|
|
52
|
+
*/
|
|
53
|
+
restore(msgId: string, redactedText: string, map: RestorationMap): string;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=raw-privacy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw-privacy.d.ts","sourceRoot":"","sources":["../../src/distiller/raw-privacy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wEAAwE;AACxE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;AAEjE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,cAAc,EAAE,cAAc,CAAC;CAChC;AAQD,qBAAa,0BAA0B;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAGlD,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,WAAW;IAInB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAsClB;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAKlC,gEAAgE;IAChE,cAAc,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,oBAAoB;IAe/D;;;;;OAKG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,MAAM;CAc1E"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RawMessagePrivacyProcessor — pre-LLM redaction (spec §4.3, first pass).
|
|
3
|
+
*
|
|
4
|
+
* The legacy block pipeline sends raw messages to the LLM and only redacts the
|
|
5
|
+
* structured ExtractionResult afterwards (privacy.ts / PrivacyProcessor) — so
|
|
6
|
+
* the model sees un-redacted originals. For the distiller we fix that ordering:
|
|
7
|
+
* this processor redacts raw message TEXT before it is ever handed to the LLM
|
|
8
|
+
* (every map/reduce segment input goes through it first).
|
|
9
|
+
*
|
|
10
|
+
* It reuses the exact PrivacyConfig rules and patterns as PrivacyProcessor, but
|
|
11
|
+
* operates on plain strings keyed by msg_id (not on ExtractionResult). In
|
|
12
|
+
* reversible mode the restoration map is grouped by msg_id (spec §4.3) so an
|
|
13
|
+
* authorized reader can recover the original text for a cited evidence range.
|
|
14
|
+
*/
|
|
15
|
+
export class RawMessagePrivacyProcessor {
|
|
16
|
+
config;
|
|
17
|
+
constructor(config) {
|
|
18
|
+
this.config = config;
|
|
19
|
+
}
|
|
20
|
+
// Patterns mirror PrivacyProcessor (privacy.ts) — same PrivacyConfig rules.
|
|
21
|
+
patterns() {
|
|
22
|
+
return [
|
|
23
|
+
{ regex: /1[3-9]\d{9}/g, replacement: "[REDACTED_PHONE]", enabled: this.config.redact_phone },
|
|
24
|
+
{ regex: /\d{17}[\dXx]/g, replacement: "[REDACTED_ID]", enabled: this.config.redact_id_card },
|
|
25
|
+
{
|
|
26
|
+
regex: /\d{16,19}/g,
|
|
27
|
+
replacement: "[REDACTED_CARD]",
|
|
28
|
+
enabled: this.config.redact_bank_card,
|
|
29
|
+
},
|
|
30
|
+
// L2 IP address — always on in PrivacyProcessor.
|
|
31
|
+
{ regex: /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/g, replacement: "[REDACTED_IP]", enabled: true },
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
escapeRegex(str) {
|
|
35
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Redact one message's text. Returns the redacted string and (in reversible
|
|
39
|
+
* mode) the ordered redaction entries.
|
|
40
|
+
*/
|
|
41
|
+
redactText(text) {
|
|
42
|
+
const entries = [];
|
|
43
|
+
let result = text;
|
|
44
|
+
const applyPattern = (regex, replacement) => {
|
|
45
|
+
const matches = [];
|
|
46
|
+
const source = result;
|
|
47
|
+
let m;
|
|
48
|
+
// biome-ignore lint/suspicious/noAssignInExpressions: standard regex.exec loop
|
|
49
|
+
while ((m = regex.exec(source)) !== null) {
|
|
50
|
+
matches.push({ original: m[0], position: m.index });
|
|
51
|
+
}
|
|
52
|
+
regex.lastIndex = 0;
|
|
53
|
+
// Apply in reverse to keep positions valid.
|
|
54
|
+
for (let i = matches.length - 1; i >= 0; i--) {
|
|
55
|
+
const mm = matches[i];
|
|
56
|
+
result =
|
|
57
|
+
result.slice(0, mm.position) +
|
|
58
|
+
replacement +
|
|
59
|
+
result.slice(mm.position + mm.original.length);
|
|
60
|
+
if (this.config.mode === "reversible") {
|
|
61
|
+
entries.push({ original: mm.original, replacement, position: mm.position });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
for (const p of this.patterns()) {
|
|
66
|
+
if (p.enabled)
|
|
67
|
+
applyPattern(p.regex, p.replacement);
|
|
68
|
+
}
|
|
69
|
+
// L3 blocked words (case-insensitive).
|
|
70
|
+
for (const word of this.config.blocked_words) {
|
|
71
|
+
const regex = new RegExp(`\\b${this.escapeRegex(word)}\\b`, "gi");
|
|
72
|
+
applyPattern(regex, this.config.replacement);
|
|
73
|
+
}
|
|
74
|
+
return { text: result, entries };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Redact a single free-text string (no restoration tracking exposed).
|
|
78
|
+
* Used by the second-pass payload privacy (payload-privacy.ts).
|
|
79
|
+
*/
|
|
80
|
+
redactString(text) {
|
|
81
|
+
if (!this.config.enabled)
|
|
82
|
+
return text;
|
|
83
|
+
return this.redactText(text).text;
|
|
84
|
+
}
|
|
85
|
+
/** Redact every message's text before it is sent to the LLM. */
|
|
86
|
+
redactMessages(messages) {
|
|
87
|
+
if (!this.config.enabled) {
|
|
88
|
+
return { messages, restorationMap: {} };
|
|
89
|
+
}
|
|
90
|
+
const restorationMap = {};
|
|
91
|
+
const redacted = messages.map((msg) => {
|
|
92
|
+
const { text, entries } = this.redactText(msg.content);
|
|
93
|
+
if (this.config.mode === "reversible" && entries.length > 0) {
|
|
94
|
+
restorationMap[msg.msgId] = entries;
|
|
95
|
+
}
|
|
96
|
+
return { ...msg, content: text };
|
|
97
|
+
});
|
|
98
|
+
return { messages: redacted, restorationMap };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Reverse redaction for a single message's (redacted) text using its
|
|
102
|
+
* msg_id-keyed entries. Applies entries in forward order (they were recorded
|
|
103
|
+
* against post-substitution offsets in reverse, so left-to-right restore is
|
|
104
|
+
* position-stable because each restore preserves earlier offsets).
|
|
105
|
+
*/
|
|
106
|
+
restore(msgId, redactedText, map) {
|
|
107
|
+
const entries = map[msgId];
|
|
108
|
+
if (!entries || entries.length === 0)
|
|
109
|
+
return redactedText;
|
|
110
|
+
// Restore from rightmost to leftmost so earlier offsets stay valid.
|
|
111
|
+
const sorted = [...entries].sort((a, b) => b.position - a.position);
|
|
112
|
+
let result = redactedText;
|
|
113
|
+
for (const e of sorted) {
|
|
114
|
+
const at = result.indexOf(e.replacement, e.position);
|
|
115
|
+
const idx = at >= 0 ? at : result.indexOf(e.replacement);
|
|
116
|
+
if (idx < 0)
|
|
117
|
+
continue;
|
|
118
|
+
result = result.slice(0, idx) + e.original + result.slice(idx + e.replacement.length);
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=raw-privacy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw-privacy.js","sourceRoot":"","sources":["../../src/distiller/raw-privacy.ts"],"names":[],"mappings":"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"}
|