@remnic/plugin-openclaw 1.0.53 → 9.3.515
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 +510 -2071
- package/openclaw.plugin.json +3 -3
- package/package.json +4 -3
- package/scripts/faiss_index.py +141 -29
- package/dist/calibration-RKL2LRW4.js +0 -250
- package/dist/capsule-cli-EHZPMXBC.js +0 -33
- package/dist/capsule-crypto-JS67OSWM.js +0 -17
- package/dist/capsule-export-DX53CPIT.js +0 -17
- package/dist/capsule-import-4OXCPHOT.js +0 -16
- package/dist/capsule-merge-25AUN33Q.js +0 -195
- package/dist/causal-chain-BVTOWZKC.js +0 -23
- package/dist/causal-consolidation-V533DIGW.js +0 -233
- package/dist/causal-retrieval-XAP6QKHZ.js +0 -182
- package/dist/causal-trajectory-graph-ZWQWZ7N5.js +0 -59
- package/dist/chunk-25J4PXDH.js +0 -30
- package/dist/chunk-2RQU6GVD.js +0 -453
- package/dist/chunk-3A5ELHTT.js +0 -61
- package/dist/chunk-3G7FAF6S.js +0 -60
- package/dist/chunk-3IKMUNW5.js +0 -177
- package/dist/chunk-4XDQ3KEC.js +0 -4048
- package/dist/chunk-5ZW5XJQ6.js +0 -128
- package/dist/chunk-6IWEAUN6.js +0 -148
- package/dist/chunk-7JOLBJJ5.js +0 -874
- package/dist/chunk-B52XADV3.js +0 -244
- package/dist/chunk-BQZ7JACP.js +0 -389
- package/dist/chunk-BU5KJVWF.js +0 -78
- package/dist/chunk-BZ4EYURA.js +0 -181
- package/dist/chunk-CEL5ZLKP.js +0 -233
- package/dist/chunk-EH4AXGRO.js +0 -48
- package/dist/chunk-I2KLQ2HA.js +0 -22
- package/dist/chunk-IO5WWY6A.js +0 -156
- package/dist/chunk-JC3FCKYL.js +0 -516
- package/dist/chunk-JZBOXOUC.js +0 -259
- package/dist/chunk-KC7KSQR4.js +0 -302
- package/dist/chunk-LZCGPRHS.js +0 -228
- package/dist/chunk-MBIFE6SA.js +0 -250
- package/dist/chunk-MWLY7VQX.js +0 -896
- package/dist/chunk-MXFJXUHC.js +0 -292
- package/dist/chunk-NUWDSTP7.js +0 -233
- package/dist/chunk-PSAPZGDX.js +0 -725
- package/dist/chunk-QCCP4RU5.js +0 -190
- package/dist/chunk-QMUQV5NP.js +0 -146
- package/dist/chunk-QQXJODFL.js +0 -328
- package/dist/chunk-QVTGUY3H.js +0 -1295
- package/dist/chunk-SWOYEQN2.js +0 -1005
- package/dist/chunk-TH5FF5SC.js +0 -16
- package/dist/chunk-TXOEHSVP.js +0 -275
- package/dist/chunk-UFU5GGGA.js +0 -47
- package/dist/chunk-UZJ7EERS.js +0 -272
- package/dist/chunk-W6EEFUCJ.js +0 -349
- package/dist/chunk-YGGGUTG3.js +0 -125
- package/dist/chunk-YJYZMLD5.js +0 -360
- package/dist/chunk-YKV4EFUI.js +0 -199
- package/dist/chunk-YXDXRE6N.js +0 -6500
- package/dist/chunk-ZS6VABML.js +0 -185
- package/dist/cipher-E23BHBSO.js +0 -27
- package/dist/consolidation-undo-FKJZCJHS.js +0 -426
- package/dist/contradiction-review-WJRWNQ5N.js +0 -29
- package/dist/contradiction-scan-5X423QGT.js +0 -12
- package/dist/dreams-ledger-KDX44I7R.js +0 -290
- package/dist/engine-7VG3IXKN.js +0 -16
- package/dist/extraction-judge-telemetry-O4ZVGLTU.js +0 -14
- package/dist/fallback-llm-43UMEXNJ.js +0 -10
- package/dist/first-start-migration-H2SAXAGR.js +0 -263
- package/dist/forget-ZECIDNL5.js +0 -68
- package/dist/fs-utils-OYXSZSVV.js +0 -39
- package/dist/graph-edge-decay-24ZKD5QL.js +0 -202
- package/dist/kdf-RXKIWHRU.js +0 -25
- package/dist/logger-XG7JKLPS.js +0 -9
- package/dist/memory-governance-TK4B4ZZ2.js +0 -25
- package/dist/metadata-WK2TRPYZ.js +0 -20
- package/dist/migrate-from-identity-anchor-SNDNKHZD.js +0 -7
- package/dist/path-ZKO74XXC.js +0 -7
- package/dist/peers-W53WSDXG.js +0 -43
- package/dist/purge-IKJISXEQ.js +0 -204
- package/dist/resolution-BN35OXDS.js +0 -11
- package/dist/secure-store-6RWYM6GK.js +0 -155
- package/dist/state-4ITLYMAU.js +0 -7
- package/dist/state-store-ET3ADVY5.js +0 -14
- package/dist/storage-HUNVVHZ7.js +0 -27
- package/dist/tier-stats-ZRQBV6G2.js +0 -147
- package/dist/trace-IL2Y34EH.js +0 -289
- package/dist/tui-7KRDCMYK.js +0 -12
- package/dist/types-MBUINTB2.js +0 -30
package/dist/chunk-W6EEFUCJ.js
DELETED
|
@@ -1,349 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
PEER_ID_PATTERN,
|
|
3
|
-
appendInteractionLog,
|
|
4
|
-
listPeers,
|
|
5
|
-
readPeerInteractionLog,
|
|
6
|
-
readPeerProfile,
|
|
7
|
-
writePeerProfile
|
|
8
|
-
} from "./chunk-7JOLBJJ5.js";
|
|
9
|
-
|
|
10
|
-
// ../remnic-core/src/peers/profile-reasoner.ts
|
|
11
|
-
function buildPeerProfileReasonerPrompt(input) {
|
|
12
|
-
const existingFields = input.existingProfile ? Object.keys(input.existingProfile.fields) : [];
|
|
13
|
-
const logBlock = input.log.map((e) => {
|
|
14
|
-
const session = e.sessionId ? ` session=${e.sessionId}` : "";
|
|
15
|
-
return `- [${e.timestamp}] (${e.kind})${session} ${e.summary}`;
|
|
16
|
-
}).join("\n");
|
|
17
|
-
return [
|
|
18
|
-
`You are an async peer-profile reasoner. Your job is to read recent interaction-log entries for one peer and propose 0..${input.maxFields} profile-field updates.`,
|
|
19
|
-
"",
|
|
20
|
-
`Peer:`,
|
|
21
|
-
` id: ${input.peer.id}`,
|
|
22
|
-
` kind: ${input.peer.kind}`,
|
|
23
|
-
` displayName: ${input.peer.displayName}`,
|
|
24
|
-
"",
|
|
25
|
-
`Existing profile field keys (preserve names when proposing updates that refine an existing field): ${existingFields.length > 0 ? existingFields.join(", ") : "(none yet)"}`,
|
|
26
|
-
"",
|
|
27
|
-
`Recent interaction log (oldest first):`,
|
|
28
|
-
logBlock.length > 0 ? logBlock : "(no entries)",
|
|
29
|
-
"",
|
|
30
|
-
`Output a single JSON object: {"proposals": [{"field": "<stable_key>", "value": "<markdown>", "signal": "<short_label>", "note": "<optional>", "sourceSessionId": "<optional>"}]}.`,
|
|
31
|
-
"",
|
|
32
|
-
`Rules:`,
|
|
33
|
-
`1. Only propose fields supported by evidence in the log. Do not invent.`,
|
|
34
|
-
`2. Keys are short snake_case (e.g. "communication_style", "tool_patterns").`,
|
|
35
|
-
`3. value is markdown. signal is a short label like "explicit_preference" or "topic_recurrence".`,
|
|
36
|
-
`4. Omit fields you can't justify. Empty proposals array is valid.`,
|
|
37
|
-
`5. Output JSON ONLY \u2014 no prose before or after.`
|
|
38
|
-
].join("\n");
|
|
39
|
-
}
|
|
40
|
-
function parsePeerProfileReasonerResponse(raw) {
|
|
41
|
-
if (typeof raw !== "string" || raw.trim() === "") return [];
|
|
42
|
-
const trimmed = raw.trim();
|
|
43
|
-
const fenced = /^```(?:json)?\s*([\s\S]*?)```\s*$/u.exec(trimmed);
|
|
44
|
-
const payload = fenced ? fenced[1].trim() : trimmed;
|
|
45
|
-
let parsed;
|
|
46
|
-
try {
|
|
47
|
-
parsed = JSON.parse(payload);
|
|
48
|
-
} catch {
|
|
49
|
-
return [];
|
|
50
|
-
}
|
|
51
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
52
|
-
return [];
|
|
53
|
-
}
|
|
54
|
-
const obj = parsed;
|
|
55
|
-
if (!Array.isArray(obj.proposals)) return [];
|
|
56
|
-
const out = [];
|
|
57
|
-
const RESERVED_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
58
|
-
for (const item of obj.proposals) {
|
|
59
|
-
if (typeof item !== "object" || item === null || Array.isArray(item)) continue;
|
|
60
|
-
const r = item;
|
|
61
|
-
if (typeof r.field !== "string" || r.field.trim() === "") continue;
|
|
62
|
-
if (RESERVED_KEYS.has(r.field)) continue;
|
|
63
|
-
if (typeof r.value !== "string" || r.value.trim() === "") continue;
|
|
64
|
-
if (typeof r.signal !== "string" || r.signal.trim() === "") continue;
|
|
65
|
-
const proposal = {
|
|
66
|
-
field: r.field,
|
|
67
|
-
value: r.value,
|
|
68
|
-
signal: r.signal,
|
|
69
|
-
...typeof r.note === "string" && r.note.length > 0 ? { note: r.note } : {},
|
|
70
|
-
...typeof r.sourceSessionId === "string" && r.sourceSessionId.length > 0 ? { sourceSessionId: r.sourceSessionId } : {}
|
|
71
|
-
};
|
|
72
|
-
out.push(proposal);
|
|
73
|
-
}
|
|
74
|
-
return out;
|
|
75
|
-
}
|
|
76
|
-
var SYSTEM_MESSAGE = 'You are a peer-profile reasoner. Output ONLY a JSON object of the form {"proposals":[{"field":"...","value":"...","signal":"...","note":"...","sourceSessionId":"..."}]}. No prose, no fenced code block, no commentary.';
|
|
77
|
-
var RUN_MARKER_KIND = "peer_profile_reasoner_run";
|
|
78
|
-
function lastRunTimestamp(log) {
|
|
79
|
-
let latest;
|
|
80
|
-
for (const entry of log) {
|
|
81
|
-
if (entry.kind !== RUN_MARKER_KIND) continue;
|
|
82
|
-
if (latest === void 0 || entry.timestamp > latest) {
|
|
83
|
-
latest = entry.timestamp;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return latest;
|
|
87
|
-
}
|
|
88
|
-
function noopLogger() {
|
|
89
|
-
return { debug: () => {
|
|
90
|
-
}, info: () => {
|
|
91
|
-
}, warn: () => {
|
|
92
|
-
} };
|
|
93
|
-
}
|
|
94
|
-
async function runPeerProfileReasoner(options) {
|
|
95
|
-
const log = {
|
|
96
|
-
debug: options.log?.debug ?? noopLogger().debug,
|
|
97
|
-
info: options.log?.info ?? noopLogger().info,
|
|
98
|
-
warn: options.log?.warn ?? noopLogger().warn
|
|
99
|
-
};
|
|
100
|
-
const result = {
|
|
101
|
-
peersConsidered: 0,
|
|
102
|
-
peersProcessed: 0,
|
|
103
|
-
fieldsApplied: 0,
|
|
104
|
-
perPeer: []
|
|
105
|
-
};
|
|
106
|
-
if (options.enabled !== true) {
|
|
107
|
-
log.debug("[peer-profile-reasoner] disabled \u2014 no-op");
|
|
108
|
-
return result;
|
|
109
|
-
}
|
|
110
|
-
if (!options.llm) {
|
|
111
|
-
log.warn("[peer-profile-reasoner] no LLM client supplied \u2014 skipping run");
|
|
112
|
-
return result;
|
|
113
|
-
}
|
|
114
|
-
const minInteractions = Number.isFinite(options.minInteractions) ? Math.max(0, Math.floor(options.minInteractions)) : 0;
|
|
115
|
-
const maxFields = Number.isFinite(options.maxFieldsPerRun) ? Math.max(0, Math.floor(options.maxFieldsPerRun)) : 0;
|
|
116
|
-
if (maxFields === 0) {
|
|
117
|
-
log.debug("[peer-profile-reasoner] maxFieldsPerRun=0 \u2014 no-op");
|
|
118
|
-
return result;
|
|
119
|
-
}
|
|
120
|
-
const maxLogPerPeer = Number.isFinite(options.maxLogEntriesPerPeer ?? NaN) ? Math.max(1, Math.floor(options.maxLogEntriesPerPeer)) : 50;
|
|
121
|
-
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
122
|
-
const nowIso = now.toISOString();
|
|
123
|
-
let peers;
|
|
124
|
-
try {
|
|
125
|
-
if (options.peerIds && options.peerIds.length > 0) {
|
|
126
|
-
const all = await listPeers(options.memoryDir);
|
|
127
|
-
const wanted = new Set(
|
|
128
|
-
options.peerIds.filter(
|
|
129
|
-
(id) => typeof id === "string" && PEER_ID_PATTERN.test(id)
|
|
130
|
-
)
|
|
131
|
-
);
|
|
132
|
-
peers = all.filter((p) => wanted.has(p.id));
|
|
133
|
-
} else {
|
|
134
|
-
peers = await listPeers(options.memoryDir);
|
|
135
|
-
}
|
|
136
|
-
} catch (err) {
|
|
137
|
-
log.warn(
|
|
138
|
-
`[peer-profile-reasoner] listPeers failed: ${err instanceof Error ? err.message : String(err)}`
|
|
139
|
-
);
|
|
140
|
-
return result;
|
|
141
|
-
}
|
|
142
|
-
result.peersConsidered = peers.length;
|
|
143
|
-
let fieldsAppliedTotal = 0;
|
|
144
|
-
for (const peer of peers) {
|
|
145
|
-
if (options.signal?.aborted) {
|
|
146
|
-
result.perPeer.push({
|
|
147
|
-
peerId: peer.id,
|
|
148
|
-
status: "skipped_aborted",
|
|
149
|
-
fieldsApplied: 0,
|
|
150
|
-
droppedDueToCap: 0,
|
|
151
|
-
fields: []
|
|
152
|
-
});
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
try {
|
|
156
|
-
const fullLog = await readPeerInteractionLog(
|
|
157
|
-
options.memoryDir,
|
|
158
|
-
peer.id
|
|
159
|
-
);
|
|
160
|
-
if (fullLog.length === 0) {
|
|
161
|
-
result.perPeer.push({
|
|
162
|
-
peerId: peer.id,
|
|
163
|
-
status: "skipped_no_log",
|
|
164
|
-
fieldsApplied: 0,
|
|
165
|
-
droppedDueToCap: 0,
|
|
166
|
-
fields: []
|
|
167
|
-
});
|
|
168
|
-
continue;
|
|
169
|
-
}
|
|
170
|
-
const lastRun = lastRunTimestamp(fullLog);
|
|
171
|
-
const sinceLastRunFull = lastRun ? fullLog.filter(
|
|
172
|
-
(e) => e.timestamp > lastRun && e.kind !== RUN_MARKER_KIND
|
|
173
|
-
) : fullLog.filter((e) => e.kind !== RUN_MARKER_KIND);
|
|
174
|
-
if (sinceLastRunFull.length < minInteractions) {
|
|
175
|
-
result.perPeer.push({
|
|
176
|
-
peerId: peer.id,
|
|
177
|
-
status: "skipped_below_min_interactions",
|
|
178
|
-
fieldsApplied: 0,
|
|
179
|
-
droppedDueToCap: 0,
|
|
180
|
-
fields: []
|
|
181
|
-
});
|
|
182
|
-
continue;
|
|
183
|
-
}
|
|
184
|
-
const sinceLastRun = sinceLastRunFull.length > maxLogPerPeer ? sinceLastRunFull.slice(sinceLastRunFull.length - maxLogPerPeer) : sinceLastRunFull;
|
|
185
|
-
const existingProfile = await readPeerProfile(options.memoryDir, peer.id);
|
|
186
|
-
const remainingBudget = maxFields - fieldsAppliedTotal;
|
|
187
|
-
if (remainingBudget <= 0) {
|
|
188
|
-
result.perPeer.push({
|
|
189
|
-
peerId: peer.id,
|
|
190
|
-
status: "skipped_cap_reached",
|
|
191
|
-
fieldsApplied: 0,
|
|
192
|
-
droppedDueToCap: 0,
|
|
193
|
-
fields: []
|
|
194
|
-
});
|
|
195
|
-
continue;
|
|
196
|
-
}
|
|
197
|
-
const prompt = buildPeerProfileReasonerPrompt({
|
|
198
|
-
peer,
|
|
199
|
-
existingProfile,
|
|
200
|
-
log: sinceLastRun,
|
|
201
|
-
maxFields: remainingBudget
|
|
202
|
-
});
|
|
203
|
-
const messages = [
|
|
204
|
-
{ role: "system", content: SYSTEM_MESSAGE },
|
|
205
|
-
{ role: "user", content: prompt }
|
|
206
|
-
];
|
|
207
|
-
let response;
|
|
208
|
-
try {
|
|
209
|
-
response = await options.llm.chatCompletion(messages, {
|
|
210
|
-
temperature: 0.2,
|
|
211
|
-
maxTokens: 1500
|
|
212
|
-
});
|
|
213
|
-
} catch (err) {
|
|
214
|
-
log.warn(
|
|
215
|
-
`[peer-profile-reasoner] LLM call failed for "${peer.id}": ${err instanceof Error ? err.message : String(err)}`
|
|
216
|
-
);
|
|
217
|
-
result.perPeer.push({
|
|
218
|
-
peerId: peer.id,
|
|
219
|
-
status: "skipped_llm_unavailable",
|
|
220
|
-
fieldsApplied: 0,
|
|
221
|
-
droppedDueToCap: 0,
|
|
222
|
-
fields: []
|
|
223
|
-
});
|
|
224
|
-
continue;
|
|
225
|
-
}
|
|
226
|
-
if (!response || typeof response.content !== "string") {
|
|
227
|
-
result.perPeer.push({
|
|
228
|
-
peerId: peer.id,
|
|
229
|
-
status: "skipped_llm_unavailable",
|
|
230
|
-
fieldsApplied: 0,
|
|
231
|
-
droppedDueToCap: 0,
|
|
232
|
-
fields: []
|
|
233
|
-
});
|
|
234
|
-
continue;
|
|
235
|
-
}
|
|
236
|
-
const proposals = parsePeerProfileReasonerResponse(response.content);
|
|
237
|
-
if (proposals.length === 0) {
|
|
238
|
-
result.perPeer.push({
|
|
239
|
-
peerId: peer.id,
|
|
240
|
-
status: "processed",
|
|
241
|
-
fieldsApplied: 0,
|
|
242
|
-
droppedDueToCap: 0,
|
|
243
|
-
fields: []
|
|
244
|
-
});
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
const sessionIdsInWindow = new Set(
|
|
248
|
-
sinceLastRun.map((e) => e.sessionId).filter((s) => typeof s === "string" && s.length > 0)
|
|
249
|
-
);
|
|
250
|
-
const baseFields = existingProfile ? { ...existingProfile.fields } : {};
|
|
251
|
-
const baseProvenance = {};
|
|
252
|
-
if (existingProfile) {
|
|
253
|
-
for (const [k, list] of Object.entries(existingProfile.provenance)) {
|
|
254
|
-
baseProvenance[k] = [...list];
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
const appliedFieldsForPeer = [];
|
|
258
|
-
let droppedDueToCap = 0;
|
|
259
|
-
let invalidProposalSeen = false;
|
|
260
|
-
for (const proposal of proposals) {
|
|
261
|
-
const candidateBudget = maxFields - fieldsAppliedTotal - appliedFieldsForPeer.length;
|
|
262
|
-
if (candidateBudget <= 0) {
|
|
263
|
-
droppedDueToCap += 1;
|
|
264
|
-
continue;
|
|
265
|
-
}
|
|
266
|
-
if (proposal.field === "__proto__" || proposal.field === "constructor" || proposal.field === "prototype") {
|
|
267
|
-
invalidProposalSeen = true;
|
|
268
|
-
continue;
|
|
269
|
-
}
|
|
270
|
-
if (!/^[a-zA-Z][a-zA-Z0-9_]{0,63}$/.test(proposal.field)) {
|
|
271
|
-
invalidProposalSeen = true;
|
|
272
|
-
continue;
|
|
273
|
-
}
|
|
274
|
-
baseFields[proposal.field] = proposal.value;
|
|
275
|
-
const sourceSessionId = proposal.sourceSessionId && sessionIdsInWindow.has(proposal.sourceSessionId) ? proposal.sourceSessionId : void 0;
|
|
276
|
-
const provEntry = {
|
|
277
|
-
observedAt: nowIso,
|
|
278
|
-
signal: proposal.signal,
|
|
279
|
-
...sourceSessionId ? { sourceSessionId } : {},
|
|
280
|
-
...proposal.note && proposal.note.length > 0 ? { note: proposal.note } : {}
|
|
281
|
-
};
|
|
282
|
-
const list = baseProvenance[proposal.field] ?? [];
|
|
283
|
-
list.push(provEntry);
|
|
284
|
-
baseProvenance[proposal.field] = list;
|
|
285
|
-
appliedFieldsForPeer.push(proposal.field);
|
|
286
|
-
}
|
|
287
|
-
if (appliedFieldsForPeer.length === 0) {
|
|
288
|
-
result.perPeer.push({
|
|
289
|
-
peerId: peer.id,
|
|
290
|
-
status: invalidProposalSeen ? "skipped_invalid_proposal" : droppedDueToCap > 0 ? "skipped_cap_reached" : "processed",
|
|
291
|
-
fieldsApplied: 0,
|
|
292
|
-
droppedDueToCap,
|
|
293
|
-
fields: []
|
|
294
|
-
});
|
|
295
|
-
continue;
|
|
296
|
-
}
|
|
297
|
-
const merged = {
|
|
298
|
-
peerId: peer.id,
|
|
299
|
-
updatedAt: nowIso,
|
|
300
|
-
fields: baseFields,
|
|
301
|
-
provenance: baseProvenance
|
|
302
|
-
};
|
|
303
|
-
await writePeerProfile(options.memoryDir, merged);
|
|
304
|
-
fieldsAppliedTotal += appliedFieldsForPeer.length;
|
|
305
|
-
const wantsMarker = options.appendRunMarkerToLog ?? true;
|
|
306
|
-
if (wantsMarker) {
|
|
307
|
-
try {
|
|
308
|
-
await appendInteractionLog(options.memoryDir, peer.id, {
|
|
309
|
-
timestamp: nowIso,
|
|
310
|
-
kind: RUN_MARKER_KIND,
|
|
311
|
-
summary: `applied ${appliedFieldsForPeer.length} field(s) via ${options.model ?? "unknown-model"}`
|
|
312
|
-
});
|
|
313
|
-
} catch (err) {
|
|
314
|
-
log.warn(
|
|
315
|
-
`[peer-profile-reasoner] run-marker append failed for "${peer.id}": ${err instanceof Error ? err.message : String(err)}`
|
|
316
|
-
);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
result.perPeer.push({
|
|
320
|
-
peerId: peer.id,
|
|
321
|
-
status: "processed",
|
|
322
|
-
fieldsApplied: appliedFieldsForPeer.length,
|
|
323
|
-
droppedDueToCap,
|
|
324
|
-
fields: appliedFieldsForPeer
|
|
325
|
-
});
|
|
326
|
-
result.peersProcessed += 1;
|
|
327
|
-
result.fieldsApplied = fieldsAppliedTotal;
|
|
328
|
-
} catch (err) {
|
|
329
|
-
log.warn(
|
|
330
|
-
`[peer-profile-reasoner] error processing peer "${peer.id}": ${err instanceof Error ? err.message : String(err)}`
|
|
331
|
-
);
|
|
332
|
-
result.perPeer.push({
|
|
333
|
-
peerId: peer.id,
|
|
334
|
-
status: "error",
|
|
335
|
-
fieldsApplied: 0,
|
|
336
|
-
droppedDueToCap: 0,
|
|
337
|
-
fields: [],
|
|
338
|
-
error: err instanceof Error ? err.message : String(err)
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
return result;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
export {
|
|
346
|
-
buildPeerProfileReasonerPrompt,
|
|
347
|
-
parsePeerProfileReasonerResponse,
|
|
348
|
-
runPeerProfileReasoner
|
|
349
|
-
};
|
package/dist/chunk-YGGGUTG3.js
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
// ../remnic-core/src/secure-store/cipher.ts
|
|
2
|
-
import { createCipheriv, createDecipheriv, randomBytes } from "crypto";
|
|
3
|
-
var ENVELOPE_VERSION = 1;
|
|
4
|
-
var IV_LENGTH = 12;
|
|
5
|
-
var AUTH_TAG_LENGTH = 16;
|
|
6
|
-
var ENVELOPE_SALT_LENGTH = 16;
|
|
7
|
-
var AES_KEY_LENGTH = 32;
|
|
8
|
-
var ENVELOPE_LAYOUT = Object.freeze({
|
|
9
|
-
version: 0,
|
|
10
|
-
salt: 1,
|
|
11
|
-
iv: 1 + ENVELOPE_SALT_LENGTH,
|
|
12
|
-
authTag: 1 + ENVELOPE_SALT_LENGTH + IV_LENGTH,
|
|
13
|
-
ciphertext: 1 + ENVELOPE_SALT_LENGTH + IV_LENGTH + AUTH_TAG_LENGTH
|
|
14
|
-
});
|
|
15
|
-
var ENVELOPE_HEADER_SIZE = ENVELOPE_LAYOUT.ciphertext;
|
|
16
|
-
function assertAesKey(key) {
|
|
17
|
-
if (!(key instanceof Uint8Array)) {
|
|
18
|
-
throw new Error("key must be a Uint8Array");
|
|
19
|
-
}
|
|
20
|
-
if (key.length !== AES_KEY_LENGTH) {
|
|
21
|
-
throw new Error(
|
|
22
|
-
`AES-256-GCM requires a ${AES_KEY_LENGTH}-byte key, got ${key.length}`
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
function seal(key, salt, plaintext, options = {}) {
|
|
27
|
-
assertAesKey(key);
|
|
28
|
-
if (!(salt instanceof Uint8Array) || salt.length !== ENVELOPE_SALT_LENGTH) {
|
|
29
|
-
throw new Error(
|
|
30
|
-
`salt must be ${ENVELOPE_SALT_LENGTH} bytes, got ${salt?.length ?? "non-buffer"}`
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
if (!(plaintext instanceof Uint8Array)) {
|
|
34
|
-
throw new Error("plaintext must be a Uint8Array");
|
|
35
|
-
}
|
|
36
|
-
let iv;
|
|
37
|
-
if (options.iv) {
|
|
38
|
-
if (options.iv.length !== IV_LENGTH) {
|
|
39
|
-
throw new Error(`iv must be ${IV_LENGTH} bytes, got ${options.iv.length}`);
|
|
40
|
-
}
|
|
41
|
-
iv = options.iv;
|
|
42
|
-
} else {
|
|
43
|
-
iv = randomBytes(IV_LENGTH);
|
|
44
|
-
}
|
|
45
|
-
const cipher = createCipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv), {
|
|
46
|
-
authTagLength: AUTH_TAG_LENGTH
|
|
47
|
-
});
|
|
48
|
-
const headerAad = buildHeaderAad(salt);
|
|
49
|
-
const finalAad = options.aad ? Buffer.concat([headerAad, Buffer.from(options.aad)]) : headerAad;
|
|
50
|
-
cipher.setAAD(finalAad);
|
|
51
|
-
const ciphertext = Buffer.concat([cipher.update(Buffer.from(plaintext)), cipher.final()]);
|
|
52
|
-
const authTag = cipher.getAuthTag();
|
|
53
|
-
if (authTag.length !== AUTH_TAG_LENGTH) {
|
|
54
|
-
throw new Error(`unexpected auth tag length: ${authTag.length}`);
|
|
55
|
-
}
|
|
56
|
-
const envelope = Buffer.alloc(ENVELOPE_HEADER_SIZE + ciphertext.length);
|
|
57
|
-
envelope.writeUInt8(ENVELOPE_VERSION, ENVELOPE_LAYOUT.version);
|
|
58
|
-
Buffer.from(salt).copy(envelope, ENVELOPE_LAYOUT.salt);
|
|
59
|
-
Buffer.from(iv).copy(envelope, ENVELOPE_LAYOUT.iv);
|
|
60
|
-
authTag.copy(envelope, ENVELOPE_LAYOUT.authTag);
|
|
61
|
-
ciphertext.copy(envelope, ENVELOPE_LAYOUT.ciphertext);
|
|
62
|
-
return envelope;
|
|
63
|
-
}
|
|
64
|
-
function parseEnvelope(envelope) {
|
|
65
|
-
if (!(envelope instanceof Uint8Array)) {
|
|
66
|
-
throw new Error("envelope must be a Uint8Array");
|
|
67
|
-
}
|
|
68
|
-
if (envelope.length < ENVELOPE_HEADER_SIZE) {
|
|
69
|
-
throw new Error(
|
|
70
|
-
`envelope too short: need \u2265 ${ENVELOPE_HEADER_SIZE} bytes, got ${envelope.length}`
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
const buf = Buffer.from(envelope.buffer, envelope.byteOffset, envelope.byteLength);
|
|
74
|
-
const version = buf.readUInt8(ENVELOPE_LAYOUT.version);
|
|
75
|
-
if (version !== ENVELOPE_VERSION) {
|
|
76
|
-
throw new Error(
|
|
77
|
-
`unsupported envelope version: ${version} (this build supports ${ENVELOPE_VERSION})`
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
return {
|
|
81
|
-
version,
|
|
82
|
-
salt: buf.subarray(ENVELOPE_LAYOUT.salt, ENVELOPE_LAYOUT.salt + ENVELOPE_SALT_LENGTH),
|
|
83
|
-
iv: buf.subarray(ENVELOPE_LAYOUT.iv, ENVELOPE_LAYOUT.iv + IV_LENGTH),
|
|
84
|
-
authTag: buf.subarray(
|
|
85
|
-
ENVELOPE_LAYOUT.authTag,
|
|
86
|
-
ENVELOPE_LAYOUT.authTag + AUTH_TAG_LENGTH
|
|
87
|
-
),
|
|
88
|
-
ciphertext: buf.subarray(ENVELOPE_LAYOUT.ciphertext)
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
function open(key, envelope, options = {}) {
|
|
92
|
-
assertAesKey(key);
|
|
93
|
-
const parsed = parseEnvelope(envelope);
|
|
94
|
-
const decipher = createDecipheriv("aes-256-gcm", Buffer.from(key), parsed.iv, {
|
|
95
|
-
authTagLength: AUTH_TAG_LENGTH
|
|
96
|
-
});
|
|
97
|
-
decipher.setAuthTag(parsed.authTag);
|
|
98
|
-
const headerAad = buildHeaderAad(parsed.salt);
|
|
99
|
-
const finalAad = options.aad ? Buffer.concat([headerAad, Buffer.from(options.aad)]) : headerAad;
|
|
100
|
-
decipher.setAAD(finalAad);
|
|
101
|
-
return Buffer.concat([decipher.update(parsed.ciphertext), decipher.final()]);
|
|
102
|
-
}
|
|
103
|
-
function buildHeaderAad(salt) {
|
|
104
|
-
const out = Buffer.alloc(1 + ENVELOPE_SALT_LENGTH);
|
|
105
|
-
out.writeUInt8(ENVELOPE_VERSION, 0);
|
|
106
|
-
Buffer.from(salt).copy(out, 1);
|
|
107
|
-
return out;
|
|
108
|
-
}
|
|
109
|
-
function generateSalt() {
|
|
110
|
-
return randomBytes(ENVELOPE_SALT_LENGTH);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export {
|
|
114
|
-
ENVELOPE_VERSION,
|
|
115
|
-
IV_LENGTH,
|
|
116
|
-
AUTH_TAG_LENGTH,
|
|
117
|
-
ENVELOPE_SALT_LENGTH,
|
|
118
|
-
AES_KEY_LENGTH,
|
|
119
|
-
ENVELOPE_LAYOUT,
|
|
120
|
-
ENVELOPE_HEADER_SIZE,
|
|
121
|
-
seal,
|
|
122
|
-
parseEnvelope,
|
|
123
|
-
open,
|
|
124
|
-
generateSalt
|
|
125
|
-
};
|