dotmem 0.0.4 → 0.0.5
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/cli.cjs +934 -33
- package/cli.js +958 -57
- package/global.cjs +1319 -30
- package/global.js +1344 -55
- package/index.cjs +1326 -37
- package/index.js +1350 -61
- package/mcp.cjs +1326 -37
- package/mcp.js +1350 -61
- package/package.json +1 -1
- package/AGENTS.md +0 -464
- package/CHANGELOG.md +0 -0
- package/COPYRIGHT.md +0 -4
- package/LICENSE.md +0 -11
- package/MEMORY.md +0 -518
- package/PACKAGE.md +0 -59
- package/README.md +0 -347
- package/SECURITY.md +0 -524
- package/llms.txt +0 -295
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { store, hlc, DEV,
|
|
1
|
+
import { store as store$1, hlc, DEV, dispatch, idb, session, state, PROD, temporal } from 'memorio';
|
|
2
2
|
export { DEV, PROD, dispatch, hlc, idb, session, state, store } from 'memorio';
|
|
3
3
|
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -5223,13 +5223,13 @@ var init_mem_repository = __esm({
|
|
|
5223
5223
|
});
|
|
5224
5224
|
}
|
|
5225
5225
|
async loadSources(sourceIds) {
|
|
5226
|
-
const { readFile:
|
|
5226
|
+
const { readFile: readFile5 } = await nodeFs4();
|
|
5227
5227
|
const ids = sourceIds ?? await this.discover();
|
|
5228
5228
|
const sources = [];
|
|
5229
5229
|
for (const sourceId of ids) {
|
|
5230
5230
|
const filePath = memFilePath(this.directoryPath, sourceId);
|
|
5231
5231
|
try {
|
|
5232
|
-
const decoded = await parseMemFile(await
|
|
5232
|
+
const decoded = await parseMemFile(await readFile5(filePath), sourceId);
|
|
5233
5233
|
sources.push({
|
|
5234
5234
|
id: sourceId,
|
|
5235
5235
|
filePath,
|
|
@@ -5313,10 +5313,10 @@ var init_mem_repository = __esm({
|
|
|
5313
5313
|
* valid package, so the backup is always a version this library can read.
|
|
5314
5314
|
*/
|
|
5315
5315
|
async keepLastValidVersion(filePath) {
|
|
5316
|
-
const { readFile:
|
|
5316
|
+
const { readFile: readFile5, copyFile, rename, rm } = await nodeFs4();
|
|
5317
5317
|
let current;
|
|
5318
5318
|
try {
|
|
5319
|
-
current = await
|
|
5319
|
+
current = await readFile5(filePath);
|
|
5320
5320
|
} catch {
|
|
5321
5321
|
return;
|
|
5322
5322
|
}
|
|
@@ -5349,7 +5349,7 @@ var init_mem_repository = __esm({
|
|
|
5349
5349
|
}
|
|
5350
5350
|
}
|
|
5351
5351
|
async writeSource(filePath, state3, preserved, preservedPackage) {
|
|
5352
|
-
const { mkdir, rename, rm, open: open2, readFile:
|
|
5352
|
+
const { mkdir, rename, rm, open: open2, readFile: readFile5 } = await nodeFs4();
|
|
5353
5353
|
if (!Number.isInteger(state3.version) || state3.version < 0) throw new Error("Invalid writable .mem knowledge version");
|
|
5354
5354
|
for (const claim2 of state3.claims) validateClaim(claim2);
|
|
5355
5355
|
await mkdir(parentPath(filePath), { recursive: true });
|
|
@@ -5371,7 +5371,7 @@ var init_mem_repository = __esm({
|
|
|
5371
5371
|
} finally {
|
|
5372
5372
|
await handle.close();
|
|
5373
5373
|
}
|
|
5374
|
-
await decodeMemArtifact(await
|
|
5374
|
+
await decodeMemArtifact(await readFile5(temporary));
|
|
5375
5375
|
await this.keepLastValidVersion(filePath);
|
|
5376
5376
|
for (let attempt = 0; attempt < 5; attempt++) {
|
|
5377
5377
|
try {
|
|
@@ -5399,8 +5399,8 @@ var init_mem_repository = __esm({
|
|
|
5399
5399
|
// core/knowledge/project-anchor.ts
|
|
5400
5400
|
async function projectAnchorExists(projectId) {
|
|
5401
5401
|
try {
|
|
5402
|
-
const { readFile:
|
|
5403
|
-
await
|
|
5402
|
+
const { readFile: readFile5 } = await import('fs/promises');
|
|
5403
|
+
await readFile5(resolveUserProjectMemoryPath(projectId));
|
|
5404
5404
|
return true;
|
|
5405
5405
|
} catch {
|
|
5406
5406
|
return false;
|
|
@@ -5465,8 +5465,8 @@ var init_user_identity = __esm({
|
|
|
5465
5465
|
"core/knowledge/user-identity.ts"() {
|
|
5466
5466
|
USER_IDENTITY_KEY = "__dotmem_user_identity__";
|
|
5467
5467
|
identityStore = null;
|
|
5468
|
-
configureUserIdentityStore = /* @__PURE__ */ __name((
|
|
5469
|
-
identityStore =
|
|
5468
|
+
configureUserIdentityStore = /* @__PURE__ */ __name((store7) => {
|
|
5469
|
+
identityStore = store7;
|
|
5470
5470
|
}, "configureUserIdentityStore");
|
|
5471
5471
|
requireStore = /* @__PURE__ */ __name(() => {
|
|
5472
5472
|
if (!identityStore) {
|
|
@@ -6081,9 +6081,155 @@ var init_staging = __esm({
|
|
|
6081
6081
|
});
|
|
6082
6082
|
|
|
6083
6083
|
// core/knowledge/loops.ts
|
|
6084
|
+
function joinPath3(base, child) {
|
|
6085
|
+
const separator3 = process.platform === "win32" ? "\\" : "/";
|
|
6086
|
+
return `${base.replace(/[\\/]+/g, separator3)}${separator3}${child}`;
|
|
6087
|
+
}
|
|
6088
|
+
function resolveLoopsFilePath() {
|
|
6089
|
+
return joinPath3(resolveUserDotMemPath(), LOOPS_FILE_NAME);
|
|
6090
|
+
}
|
|
6091
|
+
async function readFile(path) {
|
|
6092
|
+
try {
|
|
6093
|
+
const fs = await import('fs/promises');
|
|
6094
|
+
return await fs.readFile(path, "utf8");
|
|
6095
|
+
} catch {
|
|
6096
|
+
return null;
|
|
6097
|
+
}
|
|
6098
|
+
}
|
|
6099
|
+
async function writeFile(path, content) {
|
|
6100
|
+
const fs = await import('fs/promises');
|
|
6101
|
+
const dir = path.replace(/[\\/][^\\/]+$/, "");
|
|
6102
|
+
await fs.mkdir(dir, { recursive: true });
|
|
6103
|
+
const temporary = `${path}.${process.pid}.${Date.now().toString(36)}.tmp`;
|
|
6104
|
+
try {
|
|
6105
|
+
await fs.writeFile(temporary, content, "utf8");
|
|
6106
|
+
await fs.rename(temporary, path);
|
|
6107
|
+
} catch {
|
|
6108
|
+
await fs.rm(temporary, { force: true }).catch(() => void 0);
|
|
6109
|
+
throw new Error(`Failed to write loops file at ${path}`);
|
|
6110
|
+
}
|
|
6111
|
+
}
|
|
6112
|
+
function emptyDocument() {
|
|
6113
|
+
return { version: LOOPS_FORMAT_VERSION, loops: {} };
|
|
6114
|
+
}
|
|
6115
|
+
function validateDocument(value) {
|
|
6116
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
6117
|
+
throw new Error("Loops document must be an object");
|
|
6118
|
+
}
|
|
6119
|
+
const document = value;
|
|
6120
|
+
if (document.version !== LOOPS_FORMAT_VERSION) {
|
|
6121
|
+
throw new Error(`Unsupported loops document version: ${String(document.version)}`);
|
|
6122
|
+
}
|
|
6123
|
+
if (!document.loops || typeof document.loops !== "object" || Array.isArray(document.loops)) {
|
|
6124
|
+
throw new Error("Loops document loops must be an object");
|
|
6125
|
+
}
|
|
6126
|
+
const loops = {};
|
|
6127
|
+
for (const [id, loopValue] of Object.entries(document.loops)) {
|
|
6128
|
+
const loop = validateLoop(loopValue, id);
|
|
6129
|
+
loops[loop.id] = loop;
|
|
6130
|
+
}
|
|
6131
|
+
return { version: LOOPS_FORMAT_VERSION, loops };
|
|
6132
|
+
}
|
|
6133
|
+
function validateLoop(value, id) {
|
|
6134
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
6135
|
+
throw new Error(`Loop ${id} must be an object`);
|
|
6136
|
+
}
|
|
6137
|
+
const loop = value;
|
|
6138
|
+
if (typeof loop.id !== "string" || !loop.id) {
|
|
6139
|
+
throw new Error(`Loop ${id} requires an id`);
|
|
6140
|
+
}
|
|
6141
|
+
if (typeof loop.text !== "string" || !loop.text) {
|
|
6142
|
+
throw new Error(`Loop ${id} requires non-empty text`);
|
|
6143
|
+
}
|
|
6144
|
+
if (typeof loop.waitor !== "string" || !loop.waitor) {
|
|
6145
|
+
throw new Error(`Loop ${id} requires a waitor`);
|
|
6146
|
+
}
|
|
6147
|
+
if (typeof loop.openedAt !== "string" || !loop.openedAt) {
|
|
6148
|
+
throw new Error(`Loop ${id} requires an openedAt timestamp`);
|
|
6149
|
+
}
|
|
6150
|
+
const result = {
|
|
6151
|
+
id: loop.id,
|
|
6152
|
+
text: loop.text,
|
|
6153
|
+
waitor: loop.waitor,
|
|
6154
|
+
openedAt: loop.openedAt
|
|
6155
|
+
};
|
|
6156
|
+
if (typeof loop.closedAt === "string") result.closedAt = loop.closedAt;
|
|
6157
|
+
if (typeof loop.closedBy === "string") result.closedBy = loop.closedBy;
|
|
6158
|
+
if (typeof loop.closeNote === "string") result.closeNote = loop.closeNote;
|
|
6159
|
+
return result;
|
|
6160
|
+
}
|
|
6161
|
+
async function loadLoops() {
|
|
6162
|
+
const raw = await readFile(resolveLoopsFilePath());
|
|
6163
|
+
if (!raw) return emptyDocument();
|
|
6164
|
+
try {
|
|
6165
|
+
return validateDocument(JSON.parse(raw));
|
|
6166
|
+
} catch {
|
|
6167
|
+
return emptyDocument();
|
|
6168
|
+
}
|
|
6169
|
+
}
|
|
6170
|
+
async function saveLoops(document) {
|
|
6171
|
+
await writeFile(resolveLoopsFilePath(), JSON.stringify(document, null, 2) + "\n");
|
|
6172
|
+
}
|
|
6173
|
+
async function addLoop(input2) {
|
|
6174
|
+
const document = await loadLoops();
|
|
6175
|
+
if (document.loops[input2.id]) {
|
|
6176
|
+
throw new Error(`Loop ${input2.id} already exists`);
|
|
6177
|
+
}
|
|
6178
|
+
const loop = {
|
|
6179
|
+
id: input2.id,
|
|
6180
|
+
text: input2.text,
|
|
6181
|
+
waitor: input2.waitor,
|
|
6182
|
+
openedAt: input2.openedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
6183
|
+
};
|
|
6184
|
+
document.loops[loop.id] = loop;
|
|
6185
|
+
await saveLoops(document);
|
|
6186
|
+
return loop;
|
|
6187
|
+
}
|
|
6188
|
+
async function listLoops(openOnly = true) {
|
|
6189
|
+
const document = await loadLoops();
|
|
6190
|
+
const all = Object.values(document.loops);
|
|
6191
|
+
if (openOnly) {
|
|
6192
|
+
return all.filter((loop) => loop.closedAt === void 0);
|
|
6193
|
+
}
|
|
6194
|
+
return all;
|
|
6195
|
+
}
|
|
6196
|
+
async function closeLoop(id, input2) {
|
|
6197
|
+
const document = await loadLoops();
|
|
6198
|
+
const existing = document.loops[id];
|
|
6199
|
+
if (!existing) {
|
|
6200
|
+
throw new Error(`Loop ${id} not found`);
|
|
6201
|
+
}
|
|
6202
|
+
if (existing.closedAt) {
|
|
6203
|
+
throw new Error(`Loop ${id} is already closed`);
|
|
6204
|
+
}
|
|
6205
|
+
const closed = {
|
|
6206
|
+
...existing,
|
|
6207
|
+
closedAt: input2.closedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
6208
|
+
closedBy: input2.by,
|
|
6209
|
+
...input2.note ? { closeNote: input2.note } : {}
|
|
6210
|
+
};
|
|
6211
|
+
document.loops[id] = closed;
|
|
6212
|
+
await saveLoops(document);
|
|
6213
|
+
return closed;
|
|
6214
|
+
}
|
|
6215
|
+
var LOOPS_FILE_NAME, LOOPS_FORMAT_VERSION;
|
|
6084
6216
|
var init_loops = __esm({
|
|
6085
6217
|
"core/knowledge/loops.ts"() {
|
|
6086
6218
|
init_user_paths();
|
|
6219
|
+
LOOPS_FILE_NAME = "loops.json";
|
|
6220
|
+
LOOPS_FORMAT_VERSION = 1;
|
|
6221
|
+
__name(joinPath3, "joinPath");
|
|
6222
|
+
__name(resolveLoopsFilePath, "resolveLoopsFilePath");
|
|
6223
|
+
__name(readFile, "readFile");
|
|
6224
|
+
__name(writeFile, "writeFile");
|
|
6225
|
+
__name(emptyDocument, "emptyDocument");
|
|
6226
|
+
__name(validateDocument, "validateDocument");
|
|
6227
|
+
__name(validateLoop, "validateLoop");
|
|
6228
|
+
__name(loadLoops, "loadLoops");
|
|
6229
|
+
__name(saveLoops, "saveLoops");
|
|
6230
|
+
__name(addLoop, "addLoop");
|
|
6231
|
+
__name(listLoops, "listLoops");
|
|
6232
|
+
__name(closeLoop, "closeLoop");
|
|
6087
6233
|
}
|
|
6088
6234
|
});
|
|
6089
6235
|
|
|
@@ -6161,14 +6307,14 @@ var init_violations = __esm({
|
|
|
6161
6307
|
});
|
|
6162
6308
|
|
|
6163
6309
|
// core/knowledge/session.ts
|
|
6164
|
-
function
|
|
6310
|
+
function joinPath4(base, child) {
|
|
6165
6311
|
const separator3 = process.platform === "win32" ? "\\" : "/";
|
|
6166
6312
|
return `${base.replace(/[\\/]+/g, separator3)}${separator3}${child}`;
|
|
6167
6313
|
}
|
|
6168
6314
|
function resolveSessionFilePath() {
|
|
6169
|
-
return
|
|
6315
|
+
return joinPath4(resolveUserDotMemPath(), SESSION_FILE_NAME);
|
|
6170
6316
|
}
|
|
6171
|
-
async function
|
|
6317
|
+
async function readFile2(path) {
|
|
6172
6318
|
try {
|
|
6173
6319
|
const fs = await import('fs/promises');
|
|
6174
6320
|
return await fs.readFile(path, "utf8");
|
|
@@ -6177,7 +6323,7 @@ async function readFile(path) {
|
|
|
6177
6323
|
}
|
|
6178
6324
|
}
|
|
6179
6325
|
async function loadSession() {
|
|
6180
|
-
const raw = await
|
|
6326
|
+
const raw = await readFile2(resolveSessionFilePath());
|
|
6181
6327
|
if (!raw) return { ...DEFAULT_SESSION };
|
|
6182
6328
|
try {
|
|
6183
6329
|
const parsed = JSON.parse(raw);
|
|
@@ -6199,9 +6345,9 @@ var init_session = __esm({
|
|
|
6199
6345
|
"core/knowledge/session.ts"() {
|
|
6200
6346
|
init_user_paths();
|
|
6201
6347
|
SESSION_FILE_NAME = "session.json";
|
|
6202
|
-
__name(
|
|
6348
|
+
__name(joinPath4, "joinPath");
|
|
6203
6349
|
__name(resolveSessionFilePath, "resolveSessionFilePath");
|
|
6204
|
-
__name(
|
|
6350
|
+
__name(readFile2, "readFile");
|
|
6205
6351
|
DEFAULT_SESSION = {
|
|
6206
6352
|
doing: "",
|
|
6207
6353
|
changedFiles: [],
|
|
@@ -6214,16 +6360,368 @@ var init_session = __esm({
|
|
|
6214
6360
|
});
|
|
6215
6361
|
|
|
6216
6362
|
// core/knowledge/exemplars.ts
|
|
6363
|
+
function joinPath5(base, child) {
|
|
6364
|
+
const separator3 = process.platform === "win32" ? "\\" : "/";
|
|
6365
|
+
return `${base.replace(/[\\/]+/g, separator3)}${separator3}${child}`;
|
|
6366
|
+
}
|
|
6367
|
+
function resolveExemplarsPath() {
|
|
6368
|
+
return joinPath5(resolveUserDotMemPath(), EXEMPLARS_FILE_NAME);
|
|
6369
|
+
}
|
|
6370
|
+
async function readFile3(path) {
|
|
6371
|
+
try {
|
|
6372
|
+
const fs = await import('fs/promises');
|
|
6373
|
+
return await fs.readFile(path, "utf8");
|
|
6374
|
+
} catch {
|
|
6375
|
+
return null;
|
|
6376
|
+
}
|
|
6377
|
+
}
|
|
6378
|
+
async function writeFile2(path, content) {
|
|
6379
|
+
const fs = await import('fs/promises');
|
|
6380
|
+
const dir = path.replace(/[\\/][^\\/]+$/, "");
|
|
6381
|
+
await fs.mkdir(dir, { recursive: true });
|
|
6382
|
+
const temporary = `${path}.${process.pid}.${Date.now().toString(36)}.tmp`;
|
|
6383
|
+
try {
|
|
6384
|
+
await fs.writeFile(temporary, content, "utf8");
|
|
6385
|
+
await fs.rename(temporary, path);
|
|
6386
|
+
} catch {
|
|
6387
|
+
await fs.rm(temporary, { force: true }).catch(() => void 0);
|
|
6388
|
+
throw new Error(`Failed to write exemplars file at ${path}`);
|
|
6389
|
+
}
|
|
6390
|
+
}
|
|
6391
|
+
function emptyStore() {
|
|
6392
|
+
return { version: EXEMPLARS_FORMAT_VERSION, exemplars: {} };
|
|
6393
|
+
}
|
|
6394
|
+
function validateExemplar(value) {
|
|
6395
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
6396
|
+
throw new Error("Exemplar must be an object");
|
|
6397
|
+
}
|
|
6398
|
+
const e = value;
|
|
6399
|
+
if (typeof e.id !== "string" || !e.id) throw new Error("Exemplar requires non-empty id");
|
|
6400
|
+
if (typeof e.pattern !== "string" || !e.pattern) {
|
|
6401
|
+
throw new Error(`Exemplar ${e.id} requires non-empty pattern`);
|
|
6402
|
+
}
|
|
6403
|
+
const source = e.source ?? {};
|
|
6404
|
+
if (typeof source.conversationId !== "string" || !source.conversationId) {
|
|
6405
|
+
throw new Error(`Exemplar ${e.id} requires source.conversationId`);
|
|
6406
|
+
}
|
|
6407
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
6408
|
+
return {
|
|
6409
|
+
id: e.id,
|
|
6410
|
+
type: "interaction-exemplar",
|
|
6411
|
+
source: {
|
|
6412
|
+
conversationId: source.conversationId,
|
|
6413
|
+
messageIds: Array.isArray(source.messageIds) ? source.messageIds.map(String) : [],
|
|
6414
|
+
...typeof source.timestamp === "string" ? { timestamp: source.timestamp } : {}
|
|
6415
|
+
},
|
|
6416
|
+
pattern: e.pattern,
|
|
6417
|
+
originalContent: typeof e.originalContent === "string" ? e.originalContent : null,
|
|
6418
|
+
sourceReference: typeof e.sourceReference === "string" ? e.sourceReference : null,
|
|
6419
|
+
retrievalHints: Array.isArray(e.retrievalHints) ? e.retrievalHints.map(String) : [],
|
|
6420
|
+
significance: typeof e.significance === "number" && e.significance >= 0 ? e.significance : 0,
|
|
6421
|
+
confidence: typeof e.confidence === "number" && e.confidence >= 0 && e.confidence <= 1 ? e.confidence : 0,
|
|
6422
|
+
provenance: ["human-stated", "observed", "inferred"].includes(
|
|
6423
|
+
e.provenance
|
|
6424
|
+
) ? e.provenance : "observed",
|
|
6425
|
+
createdAt: typeof e.createdAt === "string" ? e.createdAt : now2,
|
|
6426
|
+
revision: typeof e.revision === "number" && e.revision > 0 ? e.revision : 1
|
|
6427
|
+
};
|
|
6428
|
+
}
|
|
6429
|
+
function validateStore(value) {
|
|
6430
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
6431
|
+
throw new Error("Exemplars document must be an object");
|
|
6432
|
+
}
|
|
6433
|
+
const doc = value;
|
|
6434
|
+
if (doc.version !== EXEMPLARS_FORMAT_VERSION) {
|
|
6435
|
+
throw new Error(`Unsupported exemplars version: ${String(doc.version)}`);
|
|
6436
|
+
}
|
|
6437
|
+
const exemplars = {};
|
|
6438
|
+
if (doc.exemplars && typeof doc.exemplars === "object" && !Array.isArray(doc.exemplars)) {
|
|
6439
|
+
for (const [_, exemplarValue] of Object.entries(doc.exemplars)) {
|
|
6440
|
+
const exemplar = validateExemplar(exemplarValue);
|
|
6441
|
+
exemplars[exemplar.id] = exemplar;
|
|
6442
|
+
}
|
|
6443
|
+
}
|
|
6444
|
+
return { version: EXEMPLARS_FORMAT_VERSION, exemplars };
|
|
6445
|
+
}
|
|
6446
|
+
async function loadExemplars() {
|
|
6447
|
+
const raw = await readFile3(resolveExemplarsPath());
|
|
6448
|
+
if (raw === null) return emptyStore();
|
|
6449
|
+
try {
|
|
6450
|
+
return validateStore(JSON.parse(raw));
|
|
6451
|
+
} catch {
|
|
6452
|
+
return emptyStore();
|
|
6453
|
+
}
|
|
6454
|
+
}
|
|
6455
|
+
async function saveExemplars(store7) {
|
|
6456
|
+
const validated = validateStore(store7);
|
|
6457
|
+
await writeFile2(resolveExemplarsPath(), JSON.stringify(validated, null, 2));
|
|
6458
|
+
}
|
|
6459
|
+
async function addExemplar(exemplar) {
|
|
6460
|
+
const store7 = await loadExemplars();
|
|
6461
|
+
if (store7.exemplars[exemplar.id]) {
|
|
6462
|
+
throw new Error(`Exemplar ${exemplar.id} already exists`);
|
|
6463
|
+
}
|
|
6464
|
+
if (exemplar.sourceReference) {
|
|
6465
|
+
const existingRef = Object.values(store7.exemplars).find(
|
|
6466
|
+
(e) => e.sourceReference === exemplar.sourceReference
|
|
6467
|
+
);
|
|
6468
|
+
if (existingRef) {
|
|
6469
|
+
throw new Error(`Exemplar with source reference ${exemplar.sourceReference} already exists (id: ${existingRef.id})`);
|
|
6470
|
+
}
|
|
6471
|
+
}
|
|
6472
|
+
const full = {
|
|
6473
|
+
...exemplar,
|
|
6474
|
+
type: "interaction-exemplar",
|
|
6475
|
+
revision: 1
|
|
6476
|
+
};
|
|
6477
|
+
store7.exemplars[exemplar.id] = full;
|
|
6478
|
+
await saveExemplars(store7);
|
|
6479
|
+
return full;
|
|
6480
|
+
}
|
|
6481
|
+
async function updateExemplar(id, updates) {
|
|
6482
|
+
const store7 = await loadExemplars();
|
|
6483
|
+
const existing = store7.exemplars[id];
|
|
6484
|
+
if (!existing) {
|
|
6485
|
+
throw new Error(`Exemplar ${id} not found`);
|
|
6486
|
+
}
|
|
6487
|
+
const updated = {
|
|
6488
|
+
...existing,
|
|
6489
|
+
...updates,
|
|
6490
|
+
id: existing.id,
|
|
6491
|
+
type: "interaction-exemplar",
|
|
6492
|
+
createdAt: existing.createdAt,
|
|
6493
|
+
revision: (updates.revision ?? existing.revision) + 1
|
|
6494
|
+
};
|
|
6495
|
+
store7.exemplars[id] = updated;
|
|
6496
|
+
await saveExemplars(store7);
|
|
6497
|
+
return updated;
|
|
6498
|
+
}
|
|
6499
|
+
var EXEMPLARS_FILE_NAME, EXEMPLARS_FORMAT_VERSION;
|
|
6217
6500
|
var init_exemplars = __esm({
|
|
6218
6501
|
"core/knowledge/exemplars.ts"() {
|
|
6219
6502
|
init_user_paths();
|
|
6503
|
+
EXEMPLARS_FILE_NAME = "exemplars.json";
|
|
6504
|
+
EXEMPLARS_FORMAT_VERSION = 1;
|
|
6505
|
+
__name(joinPath5, "joinPath");
|
|
6506
|
+
__name(resolveExemplarsPath, "resolveExemplarsPath");
|
|
6507
|
+
__name(readFile3, "readFile");
|
|
6508
|
+
__name(writeFile2, "writeFile");
|
|
6509
|
+
__name(emptyStore, "emptyStore");
|
|
6510
|
+
__name(validateExemplar, "validateExemplar");
|
|
6511
|
+
__name(validateStore, "validateStore");
|
|
6512
|
+
__name(loadExemplars, "loadExemplars");
|
|
6513
|
+
__name(saveExemplars, "saveExemplars");
|
|
6514
|
+
__name(addExemplar, "addExemplar");
|
|
6515
|
+
__name(updateExemplar, "updateExemplar");
|
|
6220
6516
|
}
|
|
6221
6517
|
});
|
|
6222
6518
|
|
|
6223
6519
|
// core/knowledge/personality-anchor.ts
|
|
6520
|
+
function joinPath6(base, child) {
|
|
6521
|
+
const separator3 = process.platform === "win32" ? "\\" : "/";
|
|
6522
|
+
return `${base.replace(/[\\/]+/g, separator3)}${separator3}${child}`;
|
|
6523
|
+
}
|
|
6524
|
+
function resolvePersonalityAnchorPath() {
|
|
6525
|
+
return joinPath6(resolveUserDotMemPath(), PERSONALITY_ANCHOR_FILE_NAME);
|
|
6526
|
+
}
|
|
6527
|
+
async function readFile4(path) {
|
|
6528
|
+
try {
|
|
6529
|
+
const fs = await import('fs/promises');
|
|
6530
|
+
return await fs.readFile(path, "utf8");
|
|
6531
|
+
} catch {
|
|
6532
|
+
return null;
|
|
6533
|
+
}
|
|
6534
|
+
}
|
|
6535
|
+
async function writeFile3(path, content) {
|
|
6536
|
+
const fs = await import('fs/promises');
|
|
6537
|
+
const dir = path.replace(/[\\/][^\\/]+$/, "");
|
|
6538
|
+
await fs.mkdir(dir, { recursive: true });
|
|
6539
|
+
const temporary = `${path}.${process.pid}.${Date.now().toString(36)}.tmp`;
|
|
6540
|
+
try {
|
|
6541
|
+
await fs.writeFile(temporary, content, "utf8");
|
|
6542
|
+
await fs.rename(temporary, path);
|
|
6543
|
+
} catch {
|
|
6544
|
+
await fs.rm(temporary, { force: true }).catch(() => void 0);
|
|
6545
|
+
throw new Error(`Failed to write personality anchor at ${path}`);
|
|
6546
|
+
}
|
|
6547
|
+
}
|
|
6548
|
+
function emptyAnchor() {
|
|
6549
|
+
const epoch = "1970-01-01T00:00:00.000Z";
|
|
6550
|
+
return {
|
|
6551
|
+
version: PERSONALITY_ANCHOR_FORMAT_VERSION,
|
|
6552
|
+
identity: {
|
|
6553
|
+
communicationStyle: [],
|
|
6554
|
+
durablePreferences: [],
|
|
6555
|
+
interactionBoundaries: []
|
|
6556
|
+
},
|
|
6557
|
+
metadata: {
|
|
6558
|
+
createdAt: epoch,
|
|
6559
|
+
updatedAt: epoch,
|
|
6560
|
+
revision: 1,
|
|
6561
|
+
sourceReferences: []
|
|
6562
|
+
}
|
|
6563
|
+
};
|
|
6564
|
+
}
|
|
6565
|
+
function validateCommunicationStyle(value) {
|
|
6566
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
6567
|
+
throw new Error("communicationStyle entry must be an object");
|
|
6568
|
+
}
|
|
6569
|
+
const style = value;
|
|
6570
|
+
if (typeof style.description !== "string" || !style.description) {
|
|
6571
|
+
throw new Error("communicationStyle entry requires non-empty description");
|
|
6572
|
+
}
|
|
6573
|
+
const confidence = style.confidence ?? "inferred";
|
|
6574
|
+
if (!["inferred", "observed", "human-stated"].includes(confidence)) {
|
|
6575
|
+
throw new Error(`Invalid confidence value: ${String(style.confidence)}`);
|
|
6576
|
+
}
|
|
6577
|
+
const evidence = Array.isArray(style.evidence) ? style.evidence.map(String) : [];
|
|
6578
|
+
return {
|
|
6579
|
+
description: style.description,
|
|
6580
|
+
confidence,
|
|
6581
|
+
evidence,
|
|
6582
|
+
lastObserved: typeof style.lastObserved === "string" ? style.lastObserved : (/* @__PURE__ */ new Date()).toISOString()
|
|
6583
|
+
};
|
|
6584
|
+
}
|
|
6585
|
+
function validateDurablePreference(value) {
|
|
6586
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
6587
|
+
throw new Error("durablePreference entry must be an object");
|
|
6588
|
+
}
|
|
6589
|
+
const pref = value;
|
|
6590
|
+
if (typeof pref.id !== "string" || !pref.id) {
|
|
6591
|
+
throw new Error("durablePreference entry requires non-empty id");
|
|
6592
|
+
}
|
|
6593
|
+
if (typeof pref.statement !== "string" || !pref.statement) {
|
|
6594
|
+
throw new Error(`durablePreference ${pref.id} requires non-empty statement`);
|
|
6595
|
+
}
|
|
6596
|
+
const confidence = pref.confidence ?? "inferred";
|
|
6597
|
+
if (!["inferred", "observed", "human-stated"].includes(confidence)) {
|
|
6598
|
+
throw new Error(`Invalid confidence value: ${String(pref.confidence)}`);
|
|
6599
|
+
}
|
|
6600
|
+
const evidence = Array.isArray(pref.evidence) ? pref.evidence.map(String) : [];
|
|
6601
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
6602
|
+
return {
|
|
6603
|
+
id: pref.id,
|
|
6604
|
+
statement: pref.statement,
|
|
6605
|
+
confidence,
|
|
6606
|
+
evidence,
|
|
6607
|
+
firstObserved: typeof pref.firstObserved === "string" ? pref.firstObserved : now2,
|
|
6608
|
+
lastConfirmed: typeof pref.lastConfirmed === "string" ? pref.lastConfirmed : now2,
|
|
6609
|
+
...typeof pref.supersededBy === "string" ? { supersededBy: pref.supersededBy } : {}
|
|
6610
|
+
};
|
|
6611
|
+
}
|
|
6612
|
+
function validateInteractionBoundary(value) {
|
|
6613
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
6614
|
+
throw new Error("interactionBoundary entry must be an object");
|
|
6615
|
+
}
|
|
6616
|
+
const boundary = value;
|
|
6617
|
+
if (typeof boundary.id !== "string" || !boundary.id) {
|
|
6618
|
+
throw new Error("interactionBoundary entry requires non-empty id");
|
|
6619
|
+
}
|
|
6620
|
+
if (typeof boundary.rule !== "string" || !boundary.rule) {
|
|
6621
|
+
throw new Error(`interactionBoundary ${boundary.id} requires non-empty rule`);
|
|
6622
|
+
}
|
|
6623
|
+
const confidence = boundary.confidence ?? "inferred";
|
|
6624
|
+
if (!["inferred", "observed", "human-stated"].includes(confidence)) {
|
|
6625
|
+
throw new Error(`Invalid confidence value: ${String(boundary.confidence)}`);
|
|
6626
|
+
}
|
|
6627
|
+
const evidence = Array.isArray(boundary.evidence) ? boundary.evidence.map(String) : [];
|
|
6628
|
+
const source = boundary.source ?? "conversation";
|
|
6629
|
+
if (!["profile", "memory", "conversation"].includes(source)) {
|
|
6630
|
+
throw new Error(`Invalid boundary source: ${String(boundary.source)}`);
|
|
6631
|
+
}
|
|
6632
|
+
return {
|
|
6633
|
+
id: boundary.id,
|
|
6634
|
+
rule: boundary.rule,
|
|
6635
|
+
confidence,
|
|
6636
|
+
evidence,
|
|
6637
|
+
source,
|
|
6638
|
+
lastConfirmed: typeof boundary.lastConfirmed === "string" ? boundary.lastConfirmed : (/* @__PURE__ */ new Date()).toISOString()
|
|
6639
|
+
};
|
|
6640
|
+
}
|
|
6641
|
+
function validateAnchor(value) {
|
|
6642
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
6643
|
+
throw new Error("Personality anchor document must be an object");
|
|
6644
|
+
}
|
|
6645
|
+
const doc = value;
|
|
6646
|
+
if (doc.version !== PERSONALITY_ANCHOR_FORMAT_VERSION) {
|
|
6647
|
+
throw new Error(`Unsupported personality anchor version: ${String(doc.version)}`);
|
|
6648
|
+
}
|
|
6649
|
+
const identity = doc.identity ?? {};
|
|
6650
|
+
const metadata = doc.metadata ?? {};
|
|
6651
|
+
const communicationStyle = Array.isArray(identity.communicationStyle) ? identity.communicationStyle.map(validateCommunicationStyle) : [];
|
|
6652
|
+
const durablePreferences = Array.isArray(identity.durablePreferences) ? identity.durablePreferences.map(validateDurablePreference) : [];
|
|
6653
|
+
const interactionBoundaries = Array.isArray(identity.interactionBoundaries) ? identity.interactionBoundaries.map(validateInteractionBoundary) : [];
|
|
6654
|
+
const sourceRefs = Array.isArray(metadata.sourceReferences) ? metadata.sourceReferences.map(String) : [];
|
|
6655
|
+
return {
|
|
6656
|
+
version: PERSONALITY_ANCHOR_FORMAT_VERSION,
|
|
6657
|
+
identity: {
|
|
6658
|
+
communicationStyle,
|
|
6659
|
+
durablePreferences,
|
|
6660
|
+
interactionBoundaries
|
|
6661
|
+
},
|
|
6662
|
+
metadata: {
|
|
6663
|
+
createdAt: typeof metadata.createdAt === "string" ? metadata.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
6664
|
+
updatedAt: typeof metadata.updatedAt === "string" ? metadata.updatedAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
6665
|
+
revision: typeof metadata.revision === "number" && metadata.revision > 0 ? metadata.revision : 1,
|
|
6666
|
+
sourceReferences: sourceRefs
|
|
6667
|
+
}
|
|
6668
|
+
};
|
|
6669
|
+
}
|
|
6670
|
+
async function loadPersonalityAnchor() {
|
|
6671
|
+
const raw = await readFile4(resolvePersonalityAnchorPath());
|
|
6672
|
+
if (raw === null) return emptyAnchor();
|
|
6673
|
+
try {
|
|
6674
|
+
const parsed = JSON.parse(raw);
|
|
6675
|
+
return validateAnchor(parsed);
|
|
6676
|
+
} catch {
|
|
6677
|
+
return emptyAnchor();
|
|
6678
|
+
}
|
|
6679
|
+
}
|
|
6680
|
+
async function savePersonalityAnchor(anchor2) {
|
|
6681
|
+
const validated = validateAnchor(anchor2);
|
|
6682
|
+
const dirPath = resolveUserDotMemPath();
|
|
6683
|
+
const fs = await import('fs/promises');
|
|
6684
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
6685
|
+
await writeFile3(resolvePersonalityAnchorPath(), JSON.stringify(validated, null, 2));
|
|
6686
|
+
}
|
|
6687
|
+
async function updatePersonalityAnchor(updates) {
|
|
6688
|
+
const existing = await loadPersonalityAnchor();
|
|
6689
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
6690
|
+
const updated = {
|
|
6691
|
+
...existing,
|
|
6692
|
+
identity: {
|
|
6693
|
+
communicationStyle: updates.communicationStyle ?? existing.identity.communicationStyle,
|
|
6694
|
+
durablePreferences: updates.durablePreferences ?? existing.identity.durablePreferences,
|
|
6695
|
+
interactionBoundaries: updates.interactionBoundaries ?? existing.identity.interactionBoundaries
|
|
6696
|
+
},
|
|
6697
|
+
metadata: {
|
|
6698
|
+
...existing.metadata,
|
|
6699
|
+
updatedAt: now2,
|
|
6700
|
+
revision: existing.metadata.revision + 1,
|
|
6701
|
+
sourceReferences: updates.sourceReferences ? [.../* @__PURE__ */ new Set([...existing.metadata.sourceReferences, ...updates.sourceReferences])] : existing.metadata.sourceReferences
|
|
6702
|
+
}
|
|
6703
|
+
};
|
|
6704
|
+
await savePersonalityAnchor(updated);
|
|
6705
|
+
return updated;
|
|
6706
|
+
}
|
|
6707
|
+
var PERSONALITY_ANCHOR_FILE_NAME, PERSONALITY_ANCHOR_FORMAT_VERSION;
|
|
6224
6708
|
var init_personality_anchor = __esm({
|
|
6225
6709
|
"core/knowledge/personality-anchor.ts"() {
|
|
6226
6710
|
init_user_paths();
|
|
6711
|
+
PERSONALITY_ANCHOR_FILE_NAME = "personality-anchor.json";
|
|
6712
|
+
PERSONALITY_ANCHOR_FORMAT_VERSION = 1;
|
|
6713
|
+
__name(joinPath6, "joinPath");
|
|
6714
|
+
__name(resolvePersonalityAnchorPath, "resolvePersonalityAnchorPath");
|
|
6715
|
+
__name(readFile4, "readFile");
|
|
6716
|
+
__name(writeFile3, "writeFile");
|
|
6717
|
+
__name(emptyAnchor, "emptyAnchor");
|
|
6718
|
+
__name(validateCommunicationStyle, "validateCommunicationStyle");
|
|
6719
|
+
__name(validateDurablePreference, "validateDurablePreference");
|
|
6720
|
+
__name(validateInteractionBoundary, "validateInteractionBoundary");
|
|
6721
|
+
__name(validateAnchor, "validateAnchor");
|
|
6722
|
+
__name(loadPersonalityAnchor, "loadPersonalityAnchor");
|
|
6723
|
+
__name(savePersonalityAnchor, "savePersonalityAnchor");
|
|
6724
|
+
__name(updatePersonalityAnchor, "updatePersonalityAnchor");
|
|
6227
6725
|
}
|
|
6228
6726
|
});
|
|
6229
6727
|
|
|
@@ -6975,19 +7473,19 @@ var journal = {
|
|
|
6975
7473
|
hlc: entry.hlc || hlc.serialize(hlc.tick())
|
|
6976
7474
|
};
|
|
6977
7475
|
const key = `${STORE_PREFIX(ns)}${row.id}`;
|
|
6978
|
-
store.set(key, row);
|
|
6979
|
-
const idx = store.get(INDEX_KEY(ns)) || [];
|
|
7476
|
+
store$1.set(key, row);
|
|
7477
|
+
const idx = store$1.get(INDEX_KEY(ns)) || [];
|
|
6980
7478
|
if (!idx.includes(row.id)) idx.push(row.id);
|
|
6981
|
-
store.set(INDEX_KEY(ns), idx);
|
|
7479
|
+
store$1.set(INDEX_KEY(ns), idx);
|
|
6982
7480
|
return row;
|
|
6983
7481
|
},
|
|
6984
7482
|
/** All pending (not-yet-synced) entries for the current namespace. */
|
|
6985
7483
|
async pending() {
|
|
6986
7484
|
const ns = namespace();
|
|
6987
7485
|
const out = [];
|
|
6988
|
-
const idx = store.get(INDEX_KEY(ns)) || [];
|
|
7486
|
+
const idx = store$1.get(INDEX_KEY(ns)) || [];
|
|
6989
7487
|
for (const id of idx) {
|
|
6990
|
-
const raw = store.get(`${STORE_PREFIX(ns)}${id}`);
|
|
7488
|
+
const raw = store$1.get(`${STORE_PREFIX(ns)}${id}`);
|
|
6991
7489
|
if (!raw) continue;
|
|
6992
7490
|
const e = parseEntry(raw);
|
|
6993
7491
|
if (e && e.sync !== "synced") out.push(e);
|
|
@@ -7010,31 +7508,31 @@ var journal = {
|
|
|
7010
7508
|
if (!ids.length) return 0;
|
|
7011
7509
|
const ns = namespace();
|
|
7012
7510
|
let count = 0;
|
|
7013
|
-
const idx = store.get(INDEX_KEY(ns)) || [];
|
|
7511
|
+
const idx = store$1.get(INDEX_KEY(ns)) || [];
|
|
7014
7512
|
for (const id of idx) {
|
|
7015
7513
|
if (!ids.includes(id)) continue;
|
|
7016
7514
|
const key = `${STORE_PREFIX(ns)}${id}`;
|
|
7017
|
-
const raw = store.get(key);
|
|
7515
|
+
const raw = store$1.get(key);
|
|
7018
7516
|
if (!raw) continue;
|
|
7019
7517
|
const e = parseEntry(raw);
|
|
7020
7518
|
if (!e || e.sync === "synced") continue;
|
|
7021
7519
|
e.sync = "synced";
|
|
7022
|
-
store.set(key, e);
|
|
7520
|
+
store$1.set(key, e);
|
|
7023
7521
|
count++;
|
|
7024
7522
|
}
|
|
7025
7523
|
return count;
|
|
7026
7524
|
},
|
|
7027
7525
|
async get(id) {
|
|
7028
7526
|
const ns = namespace();
|
|
7029
|
-
const raw = store.get(`${STORE_PREFIX(ns)}${id}`);
|
|
7527
|
+
const raw = store$1.get(`${STORE_PREFIX(ns)}${id}`);
|
|
7030
7528
|
return parseEntry(raw ?? "");
|
|
7031
7529
|
},
|
|
7032
7530
|
/** Remove all journal rows for the current namespace. */
|
|
7033
7531
|
async clear() {
|
|
7034
7532
|
const ns = namespace();
|
|
7035
|
-
const idx = store.get(INDEX_KEY(ns)) || [];
|
|
7036
|
-
for (const id of idx) store.remove(`${STORE_PREFIX(ns)}${id}`);
|
|
7037
|
-
store.remove(INDEX_KEY(ns));
|
|
7533
|
+
const idx = store$1.get(INDEX_KEY(ns)) || [];
|
|
7534
|
+
for (const id of idx) store$1.remove(`${STORE_PREFIX(ns)}${id}`);
|
|
7535
|
+
store$1.remove(INDEX_KEY(ns));
|
|
7038
7536
|
},
|
|
7039
7537
|
/**
|
|
7040
7538
|
* Reconcile the local journal against the configured provider. Pushes pending
|
|
@@ -7113,7 +7611,7 @@ var journal = {
|
|
|
7113
7611
|
*/
|
|
7114
7612
|
async status() {
|
|
7115
7613
|
try {
|
|
7116
|
-
const capabilities = store.capabilities?.();
|
|
7614
|
+
const capabilities = store$1.capabilities?.();
|
|
7117
7615
|
return capabilities?.persistent ? "store" : "memory";
|
|
7118
7616
|
} catch {
|
|
7119
7617
|
return "memory";
|
|
@@ -7174,7 +7672,7 @@ var StoreKnowledgeRepository = class {
|
|
|
7174
7672
|
__name(this, "StoreKnowledgeRepository");
|
|
7175
7673
|
}
|
|
7176
7674
|
async load() {
|
|
7177
|
-
const raw = store.get(KNOWLEDGE_STATE_KEY);
|
|
7675
|
+
const raw = store$1.get(KNOWLEDGE_STATE_KEY);
|
|
7178
7676
|
if (!raw) return { version: 0, claims: [] };
|
|
7179
7677
|
return typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
7180
7678
|
}
|
|
@@ -7184,7 +7682,7 @@ var StoreKnowledgeRepository = class {
|
|
|
7184
7682
|
if (current.version !== expectedVersion) {
|
|
7185
7683
|
throw new Error(`Stale update: expected persisted version ${expectedVersion}, received ${current.version}`);
|
|
7186
7684
|
}
|
|
7187
|
-
store.set(KNOWLEDGE_STATE_KEY, state3);
|
|
7685
|
+
store$1.set(KNOWLEDGE_STATE_KEY, state3);
|
|
7188
7686
|
}, "write");
|
|
7189
7687
|
const previous = knowledgeSaveQueue;
|
|
7190
7688
|
knowledgeSaveQueue = previous.then(write, write);
|
|
@@ -7386,27 +7884,27 @@ var auditPolicyAction = /* @__PURE__ */ __name((action, key) => {
|
|
|
7386
7884
|
}
|
|
7387
7885
|
}, "auditPolicyAction");
|
|
7388
7886
|
var resolveOverrides = /* @__PURE__ */ __name(async (namespace2, now2 = () => /* @__PURE__ */ new Date()) => {
|
|
7389
|
-
const
|
|
7887
|
+
const store7 = await getPolicyStore();
|
|
7390
7888
|
const namespaces = namespace2 ? [namespace2] : POLICY_NAMESPACES;
|
|
7391
|
-
const documents = await Promise.all(namespaces.map((entry) =>
|
|
7889
|
+
const documents = await Promise.all(namespaces.map((entry) => store7.load(entry)));
|
|
7392
7890
|
return documents.flatMap((document) => document.overrides.map(
|
|
7393
7891
|
(override) => resolveOverrideState(override, document.records.find((record2) => record2.id === override.targetPolicyId), now2)
|
|
7394
7892
|
)).sort((left, right) => left.override.id.localeCompare(right.override.id));
|
|
7395
7893
|
}, "resolveOverrides");
|
|
7396
7894
|
var policy = {
|
|
7397
7895
|
async assign(input2, namespace2 = "operator", basedOnRevision) {
|
|
7398
|
-
const
|
|
7399
|
-
const record2 = await
|
|
7896
|
+
const store7 = await getPolicyStore();
|
|
7897
|
+
const record2 = await store7.assign(input2, namespace2, basedOnRevision);
|
|
7400
7898
|
auditPolicyAction("policy.assign", record2.id);
|
|
7401
7899
|
return record2;
|
|
7402
7900
|
},
|
|
7403
7901
|
async list() {
|
|
7404
|
-
const
|
|
7405
|
-
return
|
|
7902
|
+
const store7 = await getPolicyStore();
|
|
7903
|
+
return store7.list();
|
|
7406
7904
|
},
|
|
7407
7905
|
async remove(id, namespace2 = "operator", basedOnRevision) {
|
|
7408
|
-
const
|
|
7409
|
-
await
|
|
7906
|
+
const store7 = await getPolicyStore();
|
|
7907
|
+
await store7.remove(id, namespace2, basedOnRevision);
|
|
7410
7908
|
auditPolicyAction("policy.remove", id);
|
|
7411
7909
|
},
|
|
7412
7910
|
/**
|
|
@@ -7420,16 +7918,16 @@ var policy = {
|
|
|
7420
7918
|
* the durable audit trail with a terminal CLEAR entry.
|
|
7421
7919
|
*/
|
|
7422
7920
|
async clear(authority) {
|
|
7423
|
-
const
|
|
7424
|
-
await
|
|
7921
|
+
const store7 = await getPolicyStore();
|
|
7922
|
+
await store7.clear(authority);
|
|
7425
7923
|
auditPolicyAction("policy.clear", "policy");
|
|
7426
7924
|
},
|
|
7427
7925
|
async evaluate(event, payload) {
|
|
7428
|
-
const
|
|
7926
|
+
const store7 = await getPolicyStore();
|
|
7429
7927
|
const [state3, policies, overrides] = await Promise.all([
|
|
7430
7928
|
loadCombinedKnowledgeState(),
|
|
7431
|
-
|
|
7432
|
-
|
|
7929
|
+
store7.list(),
|
|
7930
|
+
store7.listOverrides()
|
|
7433
7931
|
]);
|
|
7434
7932
|
const claims = activeClaims(state3);
|
|
7435
7933
|
return evaluatePolicies({ event, claims, policies, overrides, payload });
|
|
@@ -7451,14 +7949,14 @@ var policy = {
|
|
|
7451
7949
|
*/
|
|
7452
7950
|
override: {
|
|
7453
7951
|
async grant(input2, namespace2 = "operator", basedOnRevision) {
|
|
7454
|
-
const
|
|
7455
|
-
const override = await
|
|
7952
|
+
const store7 = await getPolicyStore();
|
|
7953
|
+
const override = await store7.grantOverride(input2, namespace2, basedOnRevision);
|
|
7456
7954
|
auditPolicyAction("policy.override", override.id);
|
|
7457
7955
|
return override;
|
|
7458
7956
|
},
|
|
7459
7957
|
async revoke(input2, namespace2 = "operator", basedOnRevision) {
|
|
7460
|
-
const
|
|
7461
|
-
const override = await
|
|
7958
|
+
const store7 = await getPolicyStore();
|
|
7959
|
+
const override = await store7.revokeOverride(input2, namespace2, basedOnRevision);
|
|
7462
7960
|
auditPolicyAction("policy.revoke", override.id);
|
|
7463
7961
|
return override;
|
|
7464
7962
|
},
|
|
@@ -7466,8 +7964,8 @@ var policy = {
|
|
|
7466
7964
|
return resolveOverrides(namespace2);
|
|
7467
7965
|
},
|
|
7468
7966
|
async effective(event, namespace2) {
|
|
7469
|
-
const
|
|
7470
|
-
const states = await
|
|
7967
|
+
const store7 = await getPolicyStore();
|
|
7968
|
+
const states = await store7.effectiveState(namespace2);
|
|
7471
7969
|
if (event === void 0) return states;
|
|
7472
7970
|
const canonical = event.trim();
|
|
7473
7971
|
return states.filter((state3) => state3.event === canonical);
|
|
@@ -7480,8 +7978,8 @@ var policy = {
|
|
|
7480
7978
|
* additional best-effort sink, and this is the durable record.
|
|
7481
7979
|
*/
|
|
7482
7980
|
async audit(namespace2) {
|
|
7483
|
-
const
|
|
7484
|
-
return
|
|
7981
|
+
const store7 = await getPolicyStore();
|
|
7982
|
+
return store7.auditTrail(namespace2);
|
|
7485
7983
|
},
|
|
7486
7984
|
contract() {
|
|
7487
7985
|
return MEMORY_PROJECTION_CONTRACT;
|
|
@@ -7627,7 +8125,7 @@ async function saveToScope(entry) {
|
|
|
7627
8125
|
session.set(storageKey, serialized);
|
|
7628
8126
|
break;
|
|
7629
8127
|
case "local":
|
|
7630
|
-
store.set(storageKey, serialized);
|
|
8128
|
+
store$1.set(storageKey, serialized);
|
|
7631
8129
|
break;
|
|
7632
8130
|
case "durable":
|
|
7633
8131
|
await idb.set("memories", storageKey, serialized);
|
|
@@ -7649,7 +8147,7 @@ async function loadFromScope(id, scope, isSuperseded = false) {
|
|
|
7649
8147
|
raw = session.get(storageKey);
|
|
7650
8148
|
break;
|
|
7651
8149
|
case "local":
|
|
7652
|
-
raw = store.get(storageKey);
|
|
8150
|
+
raw = store$1.get(storageKey);
|
|
7653
8151
|
break;
|
|
7654
8152
|
case "durable":
|
|
7655
8153
|
raw = await idb.get("memories", storageKey);
|
|
@@ -7693,7 +8191,7 @@ async function removeFromScope(id, scope, isSuperseded = false) {
|
|
|
7693
8191
|
session.remove(storageKey);
|
|
7694
8192
|
break;
|
|
7695
8193
|
case "local":
|
|
7696
|
-
store.remove(storageKey);
|
|
8194
|
+
store$1.remove(storageKey);
|
|
7697
8195
|
break;
|
|
7698
8196
|
case "durable":
|
|
7699
8197
|
await idb.deleteKey("memories", storageKey);
|
|
@@ -7704,7 +8202,7 @@ async function removeFromScope(id, scope, isSuperseded = false) {
|
|
|
7704
8202
|
__name(removeFromScope, "removeFromScope");
|
|
7705
8203
|
async function getAllIndexes() {
|
|
7706
8204
|
try {
|
|
7707
|
-
const raw = store.get(MEMORY_INDEX_KEY);
|
|
8205
|
+
const raw = store$1.get(MEMORY_INDEX_KEY);
|
|
7708
8206
|
if (!raw) return {};
|
|
7709
8207
|
return JSON.parse(raw);
|
|
7710
8208
|
} catch (err2) {
|
|
@@ -7716,7 +8214,7 @@ __name(getAllIndexes, "getAllIndexes");
|
|
|
7716
8214
|
async function updateIndex(id, scope, isSuperseded = false) {
|
|
7717
8215
|
const index = await getAllIndexes();
|
|
7718
8216
|
index[id] = { scope, superseded: isSuperseded };
|
|
7719
|
-
store.set(MEMORY_INDEX_KEY, JSON.stringify(index));
|
|
8217
|
+
store$1.set(MEMORY_INDEX_KEY, JSON.stringify(index));
|
|
7720
8218
|
}
|
|
7721
8219
|
__name(updateIndex, "updateIndex");
|
|
7722
8220
|
async function removeFromIndex(id, isSuperseded = false) {
|
|
@@ -7729,7 +8227,7 @@ async function removeFromIndex(id, isSuperseded = false) {
|
|
|
7729
8227
|
delete index[id];
|
|
7730
8228
|
}
|
|
7731
8229
|
}
|
|
7732
|
-
store.set(MEMORY_INDEX_KEY, JSON.stringify(index));
|
|
8230
|
+
store$1.set(MEMORY_INDEX_KEY, JSON.stringify(index));
|
|
7733
8231
|
}
|
|
7734
8232
|
__name(removeFromIndex, "removeFromIndex");
|
|
7735
8233
|
async function loadAll() {
|
|
@@ -7945,7 +8443,7 @@ var entries = {
|
|
|
7945
8443
|
for (const [id, info] of Object.entries(index)) {
|
|
7946
8444
|
await removeFromScope(id, info.scope, info.superseded);
|
|
7947
8445
|
}
|
|
7948
|
-
store.remove(MEMORY_INDEX_KEY);
|
|
8446
|
+
store$1.remove(MEMORY_INDEX_KEY);
|
|
7949
8447
|
},
|
|
7950
8448
|
async _getEntry(key) {
|
|
7951
8449
|
return getEntry(key);
|
|
@@ -8455,6 +8953,778 @@ var injectJoySeed = /* @__PURE__ */ __name(async (opts) => {
|
|
|
8455
8953
|
return { id: seedId, action: "stored" };
|
|
8456
8954
|
}, "injectJoySeed");
|
|
8457
8955
|
|
|
8956
|
+
// core/memory/capture-engine.ts
|
|
8957
|
+
init_exemplars();
|
|
8958
|
+
init_loops();
|
|
8959
|
+
init_personality_anchor();
|
|
8960
|
+
var CAPTURE_STATE_KEY = "__dotmem_capture_state__";
|
|
8961
|
+
var DEFAULT_CONFIG = {
|
|
8962
|
+
minSignificance: 0.3,
|
|
8963
|
+
maxItemsPerConversation: 50,
|
|
8964
|
+
dedupSimilarityThreshold: 0.75,
|
|
8965
|
+
preserveConflicts: true,
|
|
8966
|
+
tempContextTtlMs: 24 * 60 * 60 * 1e3,
|
|
8967
|
+
autoCreateExemplars: true,
|
|
8968
|
+
autoCreateLoops: true,
|
|
8969
|
+
autoCreateClaims: true
|
|
8970
|
+
};
|
|
8971
|
+
var CATEGORY_KEYWORDS = {
|
|
8972
|
+
fact: [
|
|
8973
|
+
"is",
|
|
8974
|
+
"are",
|
|
8975
|
+
"was",
|
|
8976
|
+
"were",
|
|
8977
|
+
"uses",
|
|
8978
|
+
"built with",
|
|
8979
|
+
"depends on",
|
|
8980
|
+
"located at",
|
|
8981
|
+
"named",
|
|
8982
|
+
"called",
|
|
8983
|
+
"version",
|
|
8984
|
+
"language",
|
|
8985
|
+
"framework",
|
|
8986
|
+
"test",
|
|
8987
|
+
"testing"
|
|
8988
|
+
],
|
|
8989
|
+
decision: [
|
|
8990
|
+
"decided",
|
|
8991
|
+
"decision",
|
|
8992
|
+
"agreed",
|
|
8993
|
+
"chose",
|
|
8994
|
+
"selected",
|
|
8995
|
+
"adopt",
|
|
8996
|
+
"going with",
|
|
8997
|
+
"will use",
|
|
8998
|
+
"commit to",
|
|
8999
|
+
"resolve",
|
|
9000
|
+
"settled"
|
|
9001
|
+
],
|
|
9002
|
+
experience: [
|
|
9003
|
+
"remember when",
|
|
9004
|
+
"we talked about",
|
|
9005
|
+
"discussed",
|
|
9006
|
+
"experienced",
|
|
9007
|
+
"encountered",
|
|
9008
|
+
"faced",
|
|
9009
|
+
"went through",
|
|
9010
|
+
"session",
|
|
9011
|
+
"conversation"
|
|
9012
|
+
],
|
|
9013
|
+
question: [
|
|
9014
|
+
"?",
|
|
9015
|
+
"how do",
|
|
9016
|
+
"what is",
|
|
9017
|
+
"why",
|
|
9018
|
+
"when",
|
|
9019
|
+
"where",
|
|
9020
|
+
"which",
|
|
9021
|
+
"can you",
|
|
9022
|
+
"should we",
|
|
9023
|
+
"is it possible"
|
|
9024
|
+
],
|
|
9025
|
+
open_loop: [
|
|
9026
|
+
"still need to",
|
|
9027
|
+
"pending",
|
|
9028
|
+
"waiting for",
|
|
9029
|
+
"todo",
|
|
9030
|
+
"to do",
|
|
9031
|
+
"open",
|
|
9032
|
+
"unresolved",
|
|
9033
|
+
"outstanding",
|
|
9034
|
+
"follow up",
|
|
9035
|
+
"blocked"
|
|
9036
|
+
],
|
|
9037
|
+
preference: [
|
|
9038
|
+
"prefer",
|
|
9039
|
+
"prefers",
|
|
9040
|
+
"like",
|
|
9041
|
+
"likes",
|
|
9042
|
+
"favorite",
|
|
9043
|
+
"always",
|
|
9044
|
+
"never",
|
|
9045
|
+
"don't like",
|
|
9046
|
+
"dislike",
|
|
9047
|
+
"style",
|
|
9048
|
+
"habit"
|
|
9049
|
+
],
|
|
9050
|
+
project_context: [
|
|
9051
|
+
"project",
|
|
9052
|
+
"repository",
|
|
9053
|
+
"codebase",
|
|
9054
|
+
"architecture",
|
|
9055
|
+
"stack",
|
|
9056
|
+
"deploy",
|
|
9057
|
+
"ci",
|
|
9058
|
+
"pipeline",
|
|
9059
|
+
"package"
|
|
9060
|
+
],
|
|
9061
|
+
temporary_context: [
|
|
9062
|
+
"for now",
|
|
9063
|
+
"just for",
|
|
9064
|
+
"temporary",
|
|
9065
|
+
"this session",
|
|
9066
|
+
"currently",
|
|
9067
|
+
"right now",
|
|
9068
|
+
"at the moment",
|
|
9069
|
+
"for this task"
|
|
9070
|
+
],
|
|
9071
|
+
inference: [
|
|
9072
|
+
"probably",
|
|
9073
|
+
"likely",
|
|
9074
|
+
"maybe",
|
|
9075
|
+
"perhaps",
|
|
9076
|
+
"seems",
|
|
9077
|
+
"appears",
|
|
9078
|
+
"suggests",
|
|
9079
|
+
"indicates",
|
|
9080
|
+
"implies",
|
|
9081
|
+
"might",
|
|
9082
|
+
"could be"
|
|
9083
|
+
]
|
|
9084
|
+
};
|
|
9085
|
+
var REMEMBER_PATTERNS = [
|
|
9086
|
+
/remember this/i,
|
|
9087
|
+
/remember that/i,
|
|
9088
|
+
/keep this in mind/i,
|
|
9089
|
+
/don't forget/i,
|
|
9090
|
+
/do not forget/i,
|
|
9091
|
+
/store this/i,
|
|
9092
|
+
/save this/i
|
|
9093
|
+
];
|
|
9094
|
+
var DO_NOT_REMEMBER_PATTERNS = [
|
|
9095
|
+
/don't remember/i,
|
|
9096
|
+
/do not remember/i,
|
|
9097
|
+
/forget this/i,
|
|
9098
|
+
/don't store/i,
|
|
9099
|
+
/do not store/i,
|
|
9100
|
+
/not relevant/i,
|
|
9101
|
+
/ignore this/i,
|
|
9102
|
+
/temporary only/i,
|
|
9103
|
+
/this session only/i
|
|
9104
|
+
];
|
|
9105
|
+
function generateId() {
|
|
9106
|
+
return `capture-${hlc.serialize(hlc.tick())}-${Math.random().toString(36).slice(2, 10)}`;
|
|
9107
|
+
}
|
|
9108
|
+
__name(generateId, "generateId");
|
|
9109
|
+
function nowIso() {
|
|
9110
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
9111
|
+
}
|
|
9112
|
+
__name(nowIso, "nowIso");
|
|
9113
|
+
function normalizeText(text) {
|
|
9114
|
+
return text.normalize("NFKC").toLocaleLowerCase("en-US").replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
9115
|
+
}
|
|
9116
|
+
__name(normalizeText, "normalizeText");
|
|
9117
|
+
function tokenize(text) {
|
|
9118
|
+
return new Set(normalizeText(text).split(" ").filter((t) => t.length > 2));
|
|
9119
|
+
}
|
|
9120
|
+
__name(tokenize, "tokenize");
|
|
9121
|
+
function jaccardSimilarity(a, b) {
|
|
9122
|
+
const ta = tokenize(a);
|
|
9123
|
+
const tb = tokenize(b);
|
|
9124
|
+
if (ta.size === 0 && tb.size === 0) return 1;
|
|
9125
|
+
if (ta.size === 0 || tb.size === 0) return 0;
|
|
9126
|
+
const intersection2 = new Set([...ta].filter((x2) => tb.has(x2)));
|
|
9127
|
+
const union2 = /* @__PURE__ */ new Set([...ta, ...tb]);
|
|
9128
|
+
return intersection2.size / union2.size;
|
|
9129
|
+
}
|
|
9130
|
+
__name(jaccardSimilarity, "jaccardSimilarity");
|
|
9131
|
+
function containsPhrase2(text, phrase) {
|
|
9132
|
+
const t = normalizeText(text);
|
|
9133
|
+
const p = normalizeText(phrase);
|
|
9134
|
+
return t.includes(p);
|
|
9135
|
+
}
|
|
9136
|
+
__name(containsPhrase2, "containsPhrase");
|
|
9137
|
+
function detectExplicitInstructions(text, source) {
|
|
9138
|
+
const instructions = [];
|
|
9139
|
+
for (const pattern of REMEMBER_PATTERNS) {
|
|
9140
|
+
if (pattern.test(text)) {
|
|
9141
|
+
instructions.push({
|
|
9142
|
+
type: "remember",
|
|
9143
|
+
content: text,
|
|
9144
|
+
source,
|
|
9145
|
+
timestamp: nowIso()
|
|
9146
|
+
});
|
|
9147
|
+
break;
|
|
9148
|
+
}
|
|
9149
|
+
}
|
|
9150
|
+
for (const pattern of DO_NOT_REMEMBER_PATTERNS) {
|
|
9151
|
+
if (pattern.test(text)) {
|
|
9152
|
+
instructions.push({
|
|
9153
|
+
type: "do-not-remember",
|
|
9154
|
+
content: text,
|
|
9155
|
+
source,
|
|
9156
|
+
timestamp: nowIso()
|
|
9157
|
+
});
|
|
9158
|
+
break;
|
|
9159
|
+
}
|
|
9160
|
+
}
|
|
9161
|
+
return instructions;
|
|
9162
|
+
}
|
|
9163
|
+
__name(detectExplicitInstructions, "detectExplicitInstructions");
|
|
9164
|
+
function classifyCategory(text, explicitInstructions) {
|
|
9165
|
+
const lower = text.toLocaleLowerCase("en-US");
|
|
9166
|
+
if (explicitInstructions.some((i2) => i2.type === "do-not-remember")) {
|
|
9167
|
+
return "temporary_context";
|
|
9168
|
+
}
|
|
9169
|
+
if (explicitInstructions.some((i2) => i2.type === "remember")) {
|
|
9170
|
+
if (/prefer|prefers|like|likes|favorite|always|never/i.test(lower)) {
|
|
9171
|
+
return "preference";
|
|
9172
|
+
}
|
|
9173
|
+
if (/decided|decision|agreed|chose|adopt/i.test(lower)) {
|
|
9174
|
+
return "decision";
|
|
9175
|
+
}
|
|
9176
|
+
return "fact";
|
|
9177
|
+
}
|
|
9178
|
+
const scores = {};
|
|
9179
|
+
for (const cat of Object.keys(CATEGORY_KEYWORDS)) {
|
|
9180
|
+
scores[cat] = CATEGORY_KEYWORDS[cat].filter((kw) => containsPhrase2(lower, kw)).length;
|
|
9181
|
+
}
|
|
9182
|
+
if (/probably|likely|maybe|perhaps|seems|appears|might|could be/i.test(lower)) {
|
|
9183
|
+
scores.inference += 3;
|
|
9184
|
+
}
|
|
9185
|
+
if (text.includes("?")) {
|
|
9186
|
+
scores.question += 3;
|
|
9187
|
+
}
|
|
9188
|
+
if (/decided|decision|agreed|chose|adopt|will use|going with|resolve|settled/i.test(lower)) {
|
|
9189
|
+
scores.decision += 3;
|
|
9190
|
+
}
|
|
9191
|
+
if (/prefer|prefers|like|likes|favorite|always|never|don.t like|dislike/i.test(lower)) {
|
|
9192
|
+
scores.preference += 3;
|
|
9193
|
+
}
|
|
9194
|
+
if (/still need to|pending|waiting for|todo|to do|unresolved|outstanding|follow.?up|blocked/i.test(lower)) {
|
|
9195
|
+
scores.open_loop += 3;
|
|
9196
|
+
}
|
|
9197
|
+
if (/remember when|we talked about|discussed|experienced|encountered|session|conversation/i.test(lower)) {
|
|
9198
|
+
scores.experience += 2;
|
|
9199
|
+
}
|
|
9200
|
+
if (/repository|architecture|deploy|ci|pipeline/i.test(lower)) {
|
|
9201
|
+
scores.project_context += 2;
|
|
9202
|
+
}
|
|
9203
|
+
if (/just for|this session|for now|temporary/i.test(lower)) {
|
|
9204
|
+
scores.temporary_context += 3;
|
|
9205
|
+
}
|
|
9206
|
+
if (scores.fact > 0 && scores.project_context > 0 && scores.fact === scores.project_context) {
|
|
9207
|
+
scores.fact += 1;
|
|
9208
|
+
}
|
|
9209
|
+
let bestCategory = "fact";
|
|
9210
|
+
let bestScore = -1;
|
|
9211
|
+
for (const [cat, score] of Object.entries(scores)) {
|
|
9212
|
+
if (score > bestScore) {
|
|
9213
|
+
bestScore = score;
|
|
9214
|
+
bestCategory = cat;
|
|
9215
|
+
}
|
|
9216
|
+
}
|
|
9217
|
+
if (bestScore === 0) return "fact";
|
|
9218
|
+
return bestCategory;
|
|
9219
|
+
}
|
|
9220
|
+
__name(classifyCategory, "classifyCategory");
|
|
9221
|
+
function determineEpistemicType(category, text, explicitInstructions) {
|
|
9222
|
+
if (explicitInstructions.some((i2) => i2.type === "remember")) {
|
|
9223
|
+
return "human-stated";
|
|
9224
|
+
}
|
|
9225
|
+
if (category === "inference" || /probably|likely|maybe|perhaps|seems|appears/i.test(text)) {
|
|
9226
|
+
return "inferred";
|
|
9227
|
+
}
|
|
9228
|
+
if (category === "question") return "observed";
|
|
9229
|
+
return "observed";
|
|
9230
|
+
}
|
|
9231
|
+
__name(determineEpistemicType, "determineEpistemicType");
|
|
9232
|
+
function determineConfidence(category, epistemicType, _text) {
|
|
9233
|
+
if (epistemicType === "human-stated") return "high";
|
|
9234
|
+
if (epistemicType === "inferred") return "low";
|
|
9235
|
+
if (category === "decision" || category === "preference") return "medium";
|
|
9236
|
+
if (category === "question") return "medium";
|
|
9237
|
+
if (category === "fact") return "medium";
|
|
9238
|
+
return "low";
|
|
9239
|
+
}
|
|
9240
|
+
__name(determineConfidence, "determineConfidence");
|
|
9241
|
+
function extractEntities(text) {
|
|
9242
|
+
const entities = [];
|
|
9243
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9244
|
+
const capitalizedMatches = text.match(/\b[A-Z][a-zA-Z]+(?:\s+[A-Z][a-zA-Z]+)*\b/g) || [];
|
|
9245
|
+
for (const match of capitalizedMatches) {
|
|
9246
|
+
if (seen.has(match)) continue;
|
|
9247
|
+
seen.add(match);
|
|
9248
|
+
entities.push({
|
|
9249
|
+
id: `entity-${normalizeText(match)}`,
|
|
9250
|
+
type: "concept",
|
|
9251
|
+
name: match,
|
|
9252
|
+
aliases: [],
|
|
9253
|
+
relationships: []
|
|
9254
|
+
});
|
|
9255
|
+
}
|
|
9256
|
+
const quotedMatches = text.match(/["'`]([^"`']{2,})["'`]/g) || [];
|
|
9257
|
+
for (const match of quotedMatches) {
|
|
9258
|
+
const clean = match.replace(/["'`]/g, "");
|
|
9259
|
+
if (seen.has(clean)) continue;
|
|
9260
|
+
seen.add(clean);
|
|
9261
|
+
entities.push({
|
|
9262
|
+
id: `entity-${normalizeText(clean)}`,
|
|
9263
|
+
type: "concept",
|
|
9264
|
+
name: clean,
|
|
9265
|
+
aliases: [],
|
|
9266
|
+
relationships: []
|
|
9267
|
+
});
|
|
9268
|
+
}
|
|
9269
|
+
return entities;
|
|
9270
|
+
}
|
|
9271
|
+
__name(extractEntities, "extractEntities");
|
|
9272
|
+
function extractRelationships(_text, entities) {
|
|
9273
|
+
const relationships = [];
|
|
9274
|
+
if (entities.length < 2) return relationships;
|
|
9275
|
+
for (let i2 = 0; i2 < entities.length - 1; i2++) {
|
|
9276
|
+
for (let j = i2 + 1; j < entities.length; j++) {
|
|
9277
|
+
relationships.push({
|
|
9278
|
+
from: entities[i2].id,
|
|
9279
|
+
to: entities[j].id,
|
|
9280
|
+
type: "related-to",
|
|
9281
|
+
confidence: 0.5
|
|
9282
|
+
});
|
|
9283
|
+
}
|
|
9284
|
+
}
|
|
9285
|
+
return relationships;
|
|
9286
|
+
}
|
|
9287
|
+
__name(extractRelationships, "extractRelationships");
|
|
9288
|
+
async function findExistingSimilarItems(statement, category, existingItems, threshold) {
|
|
9289
|
+
const matches2 = [];
|
|
9290
|
+
for (const existing of existingItems) {
|
|
9291
|
+
if (existing.category !== category) continue;
|
|
9292
|
+
const similarity = jaccardSimilarity(statement, existing.statement);
|
|
9293
|
+
if (similarity >= threshold) {
|
|
9294
|
+
matches2.push({
|
|
9295
|
+
existingId: existing.id,
|
|
9296
|
+
existingStatement: existing.statement,
|
|
9297
|
+
similarity,
|
|
9298
|
+
matchType: similarity >= 0.95 ? "exact" : "semantic",
|
|
9299
|
+
category: existing.category
|
|
9300
|
+
});
|
|
9301
|
+
}
|
|
9302
|
+
}
|
|
9303
|
+
return matches2;
|
|
9304
|
+
}
|
|
9305
|
+
__name(findExistingSimilarItems, "findExistingSimilarItems");
|
|
9306
|
+
async function findExistingMemoryEntries(statement, category) {
|
|
9307
|
+
const matches2 = [];
|
|
9308
|
+
try {
|
|
9309
|
+
const all = await entries._loadAll();
|
|
9310
|
+
for (const entry of all) {
|
|
9311
|
+
if (entry.status !== "active") continue;
|
|
9312
|
+
if (entry.type !== category && entry.type !== "fact") continue;
|
|
9313
|
+
const entryText = typeof entry.value === "string" ? entry.value : JSON.stringify(entry.value);
|
|
9314
|
+
const similarity = jaccardSimilarity(statement, entryText);
|
|
9315
|
+
if (similarity >= DEFAULT_CONFIG.dedupSimilarityThreshold) {
|
|
9316
|
+
matches2.push({
|
|
9317
|
+
existingId: entry.id,
|
|
9318
|
+
existingStatement: entryText,
|
|
9319
|
+
similarity,
|
|
9320
|
+
matchType: similarity >= 0.95 ? "exact" : "semantic",
|
|
9321
|
+
category
|
|
9322
|
+
});
|
|
9323
|
+
}
|
|
9324
|
+
}
|
|
9325
|
+
} catch {
|
|
9326
|
+
}
|
|
9327
|
+
return matches2;
|
|
9328
|
+
}
|
|
9329
|
+
__name(findExistingMemoryEntries, "findExistingMemoryEntries");
|
|
9330
|
+
function shouldStoreInCoreMemory(category, epistemicType) {
|
|
9331
|
+
return category === "preference" && epistemicType === "human-stated";
|
|
9332
|
+
}
|
|
9333
|
+
__name(shouldStoreInCoreMemory, "shouldStoreInCoreMemory");
|
|
9334
|
+
async function routeToStorage(item, adapters, config2) {
|
|
9335
|
+
const { category, epistemicType, statement, entities, provenance, confidence } = item;
|
|
9336
|
+
const memKey = `capture:${item.id}`;
|
|
9337
|
+
await entries.remember(memKey, {
|
|
9338
|
+
id: item.id,
|
|
9339
|
+
category,
|
|
9340
|
+
statement,
|
|
9341
|
+
entities,
|
|
9342
|
+
relationships: item.relationships,
|
|
9343
|
+
provenance,
|
|
9344
|
+
confidence,
|
|
9345
|
+
epistemicType,
|
|
9346
|
+
capturedAt: provenance.capturedAt
|
|
9347
|
+
}, {
|
|
9348
|
+
id: item.id,
|
|
9349
|
+
type: category === "preference" ? "preference" : category === "decision" ? "decision" : category === "fact" ? "fact" : "context",
|
|
9350
|
+
confidence: confidence === "high" ? 1 : confidence === "medium" ? 0.7 : 0.4,
|
|
9351
|
+
scope: category === "temporary_context" ? "session" : "local",
|
|
9352
|
+
tags: [category, provenance.epistemicType, provenance.source.conversationId],
|
|
9353
|
+
source: `capture:${provenance.source.conversationId}`
|
|
9354
|
+
});
|
|
9355
|
+
if (shouldStoreInCoreMemory(category, epistemicType)) {
|
|
9356
|
+
try {
|
|
9357
|
+
const anchor2 = await loadPersonalityAnchor();
|
|
9358
|
+
const existingPref = anchor2.identity.durablePreferences.find((p) => p.statement === statement);
|
|
9359
|
+
if (!existingPref) {
|
|
9360
|
+
await updatePersonalityAnchor({
|
|
9361
|
+
durablePreferences: [
|
|
9362
|
+
...anchor2.identity.durablePreferences,
|
|
9363
|
+
{
|
|
9364
|
+
id: item.id,
|
|
9365
|
+
statement,
|
|
9366
|
+
confidence: epistemicType,
|
|
9367
|
+
evidence: [provenance.source.conversationId],
|
|
9368
|
+
firstObserved: provenance.capturedAt,
|
|
9369
|
+
lastConfirmed: provenance.capturedAt
|
|
9370
|
+
}
|
|
9371
|
+
]
|
|
9372
|
+
});
|
|
9373
|
+
}
|
|
9374
|
+
} catch {
|
|
9375
|
+
}
|
|
9376
|
+
}
|
|
9377
|
+
if (category === "open_loop" && config2.autoCreateLoops) {
|
|
9378
|
+
try {
|
|
9379
|
+
const existingLoops = await listLoops(true);
|
|
9380
|
+
const alreadyExists = existingLoops.some((l) => l.text === statement);
|
|
9381
|
+
if (!alreadyExists) {
|
|
9382
|
+
await addLoop({
|
|
9383
|
+
id: item.id,
|
|
9384
|
+
text: statement,
|
|
9385
|
+
waitor: "joy",
|
|
9386
|
+
openedAt: provenance.capturedAt
|
|
9387
|
+
});
|
|
9388
|
+
}
|
|
9389
|
+
} catch {
|
|
9390
|
+
}
|
|
9391
|
+
}
|
|
9392
|
+
if (category === "experience" && config2.autoCreateExemplars) {
|
|
9393
|
+
try {
|
|
9394
|
+
await addExemplar({
|
|
9395
|
+
id: item.id,
|
|
9396
|
+
source: {
|
|
9397
|
+
conversationId: provenance.source.conversationId,
|
|
9398
|
+
messageIds: provenance.source.messageIds
|
|
9399
|
+
},
|
|
9400
|
+
pattern: statement,
|
|
9401
|
+
originalContent: statement,
|
|
9402
|
+
sourceReference: `capture:${item.id}`,
|
|
9403
|
+
retrievalHints: [statement, ...entities.map((e) => e.name)],
|
|
9404
|
+
significance: confidence === "high" ? 0.8 : confidence === "medium" ? 0.5 : 0.3,
|
|
9405
|
+
confidence: confidence === "high" ? 1 : confidence === "medium" ? 0.7 : 0.4,
|
|
9406
|
+
provenance: epistemicType,
|
|
9407
|
+
createdAt: provenance.capturedAt
|
|
9408
|
+
});
|
|
9409
|
+
} catch {
|
|
9410
|
+
}
|
|
9411
|
+
}
|
|
9412
|
+
if (config2.autoCreateClaims && (category === "fact" || category === "decision")) {
|
|
9413
|
+
try {
|
|
9414
|
+
await acquire.acquire({
|
|
9415
|
+
id: `claim-${item.id}`,
|
|
9416
|
+
knowledge: { statement, category },
|
|
9417
|
+
applicability: { area: "project" },
|
|
9418
|
+
evidence: [{
|
|
9419
|
+
id: `ev-${item.id}`,
|
|
9420
|
+
source: provenance.source.conversationId,
|
|
9421
|
+
observedAt: provenance.capturedAt,
|
|
9422
|
+
supports: statement
|
|
9423
|
+
}],
|
|
9424
|
+
epistemicType,
|
|
9425
|
+
provenance: { source: "conversation-capture", detail: `category:${category}` },
|
|
9426
|
+
acquiredAt: provenance.capturedAt,
|
|
9427
|
+
scope: "project"
|
|
9428
|
+
});
|
|
9429
|
+
} catch {
|
|
9430
|
+
}
|
|
9431
|
+
}
|
|
9432
|
+
dispatch.set("dotmem:capture:item-captured", {
|
|
9433
|
+
detail: { id: item.id, category, statement }
|
|
9434
|
+
});
|
|
9435
|
+
}
|
|
9436
|
+
__name(routeToStorage, "routeToStorage");
|
|
9437
|
+
var CaptureEngine = class {
|
|
9438
|
+
static {
|
|
9439
|
+
__name(this, "CaptureEngine");
|
|
9440
|
+
}
|
|
9441
|
+
config;
|
|
9442
|
+
adapters;
|
|
9443
|
+
sessionContexts = /* @__PURE__ */ new Map();
|
|
9444
|
+
constructor(config2 = {}, adapters) {
|
|
9445
|
+
this.config = { ...DEFAULT_CONFIG, ...config2 };
|
|
9446
|
+
this.adapters = {
|
|
9447
|
+
remember: entries.remember.bind(entries),
|
|
9448
|
+
recall: entries.recall.bind(entries),
|
|
9449
|
+
update: entries.update.bind(entries),
|
|
9450
|
+
addExemplar: addExemplar.bind(null),
|
|
9451
|
+
updateExemplar: updateExemplar.bind(null),
|
|
9452
|
+
addLoop: addLoop.bind(null),
|
|
9453
|
+
closeLoop: closeLoop.bind(null),
|
|
9454
|
+
updatePersonalityAnchor: updatePersonalityAnchor.bind(null),
|
|
9455
|
+
...adapters
|
|
9456
|
+
};
|
|
9457
|
+
}
|
|
9458
|
+
/**
|
|
9459
|
+
* Capture information from a conversation turn.
|
|
9460
|
+
* Processes a single message or turn of conversation.
|
|
9461
|
+
*/
|
|
9462
|
+
async captureTurn(text, options) {
|
|
9463
|
+
const source = {
|
|
9464
|
+
conversationId: options.conversationId,
|
|
9465
|
+
messageIds: options.messageIds ?? [],
|
|
9466
|
+
timestamp: nowIso(),
|
|
9467
|
+
turnIndex: 0
|
|
9468
|
+
};
|
|
9469
|
+
const instructions = detectExplicitInstructions(text, source);
|
|
9470
|
+
const hasDoNotRemember = instructions.some((i2) => i2.type === "do-not-remember");
|
|
9471
|
+
const hasExplicitRemember = instructions.some((i2) => i2.type === "remember");
|
|
9472
|
+
let created = 0, linked = 0, ignored = 0;
|
|
9473
|
+
if (hasDoNotRemember && !hasExplicitRemember) {
|
|
9474
|
+
const item2 = {
|
|
9475
|
+
id: generateId(),
|
|
9476
|
+
category: "temporary_context",
|
|
9477
|
+
statement: text,
|
|
9478
|
+
content: { text },
|
|
9479
|
+
entities: [],
|
|
9480
|
+
relationships: [],
|
|
9481
|
+
provenance: {
|
|
9482
|
+
source,
|
|
9483
|
+
classification: "temporary_context",
|
|
9484
|
+
confidence: "low",
|
|
9485
|
+
epistemicType: "observed",
|
|
9486
|
+
capturedAt: nowIso(),
|
|
9487
|
+
method: "automatic"
|
|
9488
|
+
},
|
|
9489
|
+
confidence: "low",
|
|
9490
|
+
epistemicType: "observed"
|
|
9491
|
+
};
|
|
9492
|
+
await this.storeSessionContext(options.conversationId, [item2], instructions);
|
|
9493
|
+
ignored++;
|
|
9494
|
+
return { items: [item2], instructions, created: 0, linked: 0, ignored: 1, dedupMatches: [] };
|
|
9495
|
+
}
|
|
9496
|
+
const category = classifyCategory(text, instructions);
|
|
9497
|
+
const epistemicType = determineEpistemicType(category, text, instructions);
|
|
9498
|
+
const confidence = determineConfidence(category, epistemicType);
|
|
9499
|
+
const entities = extractEntities(text);
|
|
9500
|
+
const relationships = extractRelationships(text, entities);
|
|
9501
|
+
const provenance = {
|
|
9502
|
+
source,
|
|
9503
|
+
classification: category,
|
|
9504
|
+
confidence,
|
|
9505
|
+
epistemicType,
|
|
9506
|
+
capturedAt: nowIso(),
|
|
9507
|
+
method: hasExplicitRemember ? "explicit" : "automatic"
|
|
9508
|
+
};
|
|
9509
|
+
const item = {
|
|
9510
|
+
id: generateId(),
|
|
9511
|
+
category,
|
|
9512
|
+
statement: text,
|
|
9513
|
+
content: { text },
|
|
9514
|
+
entities,
|
|
9515
|
+
relationships,
|
|
9516
|
+
provenance,
|
|
9517
|
+
confidence,
|
|
9518
|
+
epistemicType
|
|
9519
|
+
};
|
|
9520
|
+
const sessionCtx = this.sessionContexts.get(options.conversationId);
|
|
9521
|
+
const existingItems = sessionCtx ? sessionCtx.items : [];
|
|
9522
|
+
const dedupMatches = await findExistingSimilarItems(
|
|
9523
|
+
text,
|
|
9524
|
+
category,
|
|
9525
|
+
existingItems,
|
|
9526
|
+
this.config.dedupSimilarityThreshold
|
|
9527
|
+
);
|
|
9528
|
+
const memoryMatches = await findExistingMemoryEntries(text, category);
|
|
9529
|
+
const allMatches = [...dedupMatches, ...memoryMatches];
|
|
9530
|
+
let decision = "create";
|
|
9531
|
+
if (allMatches.length > 0) {
|
|
9532
|
+
const exactMatch = allMatches.find((m) => m.matchType === "exact");
|
|
9533
|
+
if (exactMatch) {
|
|
9534
|
+
decision = "link";
|
|
9535
|
+
linked++;
|
|
9536
|
+
} else {
|
|
9537
|
+
decision = "create";
|
|
9538
|
+
created++;
|
|
9539
|
+
}
|
|
9540
|
+
} else {
|
|
9541
|
+
created++;
|
|
9542
|
+
}
|
|
9543
|
+
const finalItem = { ...item };
|
|
9544
|
+
const shouldStore = decision === "create" || decision === "link";
|
|
9545
|
+
if (shouldStore) {
|
|
9546
|
+
await routeToStorage(finalItem, this.adapters, this.config);
|
|
9547
|
+
}
|
|
9548
|
+
await this.storeSessionContext(options.conversationId, [finalItem], instructions);
|
|
9549
|
+
return { items: [finalItem], instructions, created, linked, ignored, dedupMatches: allMatches };
|
|
9550
|
+
}
|
|
9551
|
+
/**
|
|
9552
|
+
* Capture information from a full conversation (array of messages).
|
|
9553
|
+
* Processes each message and returns aggregated results.
|
|
9554
|
+
*/
|
|
9555
|
+
async captureConversation(messages, options) {
|
|
9556
|
+
const allItems = [];
|
|
9557
|
+
const allInstructions = [];
|
|
9558
|
+
let created = 0, updated = 0, linked = 0, ignored = 0;
|
|
9559
|
+
const allDedupMatches = [];
|
|
9560
|
+
for (const [index, msg] of messages.entries()) {
|
|
9561
|
+
const source = {
|
|
9562
|
+
conversationId: options.conversationId,
|
|
9563
|
+
messageIds: [msg.id ?? `msg-${index}`],
|
|
9564
|
+
timestamp: msg.timestamp ?? nowIso(),
|
|
9565
|
+
turnIndex: index
|
|
9566
|
+
};
|
|
9567
|
+
const instructions = detectExplicitInstructions(msg.content, source);
|
|
9568
|
+
allInstructions.push(...instructions);
|
|
9569
|
+
const hasDoNotRemember = instructions.some((i2) => i2.type === "do-not-remember");
|
|
9570
|
+
const hasExplicitRemember = instructions.some((i2) => i2.type === "remember");
|
|
9571
|
+
if (hasDoNotRemember && !hasExplicitRemember) {
|
|
9572
|
+
const item2 = {
|
|
9573
|
+
id: generateId(),
|
|
9574
|
+
category: "temporary_context",
|
|
9575
|
+
statement: msg.content,
|
|
9576
|
+
content: { text: msg.content, role: msg.role },
|
|
9577
|
+
entities: [],
|
|
9578
|
+
relationships: [],
|
|
9579
|
+
provenance: {
|
|
9580
|
+
source,
|
|
9581
|
+
classification: "temporary_context",
|
|
9582
|
+
confidence: "low",
|
|
9583
|
+
epistemicType: "observed",
|
|
9584
|
+
capturedAt: nowIso(),
|
|
9585
|
+
method: "automatic"
|
|
9586
|
+
},
|
|
9587
|
+
confidence: "low",
|
|
9588
|
+
epistemicType: "observed"
|
|
9589
|
+
};
|
|
9590
|
+
allItems.push(item2);
|
|
9591
|
+
ignored++;
|
|
9592
|
+
continue;
|
|
9593
|
+
}
|
|
9594
|
+
const category = classifyCategory(msg.content, instructions);
|
|
9595
|
+
const epistemicType = determineEpistemicType(category, msg.content, instructions);
|
|
9596
|
+
const confidence = determineConfidence(category, epistemicType, msg.content);
|
|
9597
|
+
const entities = extractEntities(msg.content);
|
|
9598
|
+
const relationships = extractRelationships(msg.content, entities);
|
|
9599
|
+
const provenance = {
|
|
9600
|
+
source,
|
|
9601
|
+
classification: category,
|
|
9602
|
+
confidence,
|
|
9603
|
+
epistemicType,
|
|
9604
|
+
capturedAt: nowIso(),
|
|
9605
|
+
method: hasExplicitRemember ? "explicit" : "automatic"
|
|
9606
|
+
};
|
|
9607
|
+
const item = {
|
|
9608
|
+
id: generateId(),
|
|
9609
|
+
category,
|
|
9610
|
+
statement: msg.content,
|
|
9611
|
+
content: { text: msg.content, role: msg.role },
|
|
9612
|
+
entities,
|
|
9613
|
+
relationships,
|
|
9614
|
+
provenance,
|
|
9615
|
+
confidence,
|
|
9616
|
+
epistemicType
|
|
9617
|
+
};
|
|
9618
|
+
const dedupMatches = await findExistingSimilarItems(
|
|
9619
|
+
msg.content,
|
|
9620
|
+
category,
|
|
9621
|
+
allItems,
|
|
9622
|
+
this.config.dedupSimilarityThreshold
|
|
9623
|
+
);
|
|
9624
|
+
const memoryMatches = await findExistingMemoryEntries(msg.content, category);
|
|
9625
|
+
const allMatches = [...dedupMatches, ...memoryMatches];
|
|
9626
|
+
allDedupMatches.push(...allMatches);
|
|
9627
|
+
let decision = "create";
|
|
9628
|
+
if (allMatches.length > 0) {
|
|
9629
|
+
const exactMatch = allMatches.find((m) => m.matchType === "exact");
|
|
9630
|
+
if (exactMatch) {
|
|
9631
|
+
decision = "link";
|
|
9632
|
+
linked++;
|
|
9633
|
+
} else {
|
|
9634
|
+
decision = "create";
|
|
9635
|
+
created++;
|
|
9636
|
+
}
|
|
9637
|
+
} else {
|
|
9638
|
+
created++;
|
|
9639
|
+
}
|
|
9640
|
+
const shouldStore = decision === "create" || decision === "link";
|
|
9641
|
+
if (shouldStore) {
|
|
9642
|
+
await routeToStorage(item, this.adapters, this.config);
|
|
9643
|
+
}
|
|
9644
|
+
if (!shouldStore) ignored++;
|
|
9645
|
+
allItems.push(item);
|
|
9646
|
+
}
|
|
9647
|
+
await this.storeSessionContext(options.conversationId, allItems, allInstructions);
|
|
9648
|
+
return {
|
|
9649
|
+
items: allItems,
|
|
9650
|
+
created,
|
|
9651
|
+
updated,
|
|
9652
|
+
linked,
|
|
9653
|
+
ignored,
|
|
9654
|
+
dedupMatches: allDedupMatches,
|
|
9655
|
+
provenance: allItems.map((i2) => i2.provenance)
|
|
9656
|
+
};
|
|
9657
|
+
}
|
|
9658
|
+
/**
|
|
9659
|
+
* Retrieve captured items for a conversation.
|
|
9660
|
+
*/
|
|
9661
|
+
async getCapturedItems(conversationId) {
|
|
9662
|
+
const ctx = this.sessionContexts.get(conversationId);
|
|
9663
|
+
return ctx ? ctx.items : [];
|
|
9664
|
+
}
|
|
9665
|
+
/**
|
|
9666
|
+
* Get all captured items across all conversations.
|
|
9667
|
+
*/
|
|
9668
|
+
async getAllCapturedItems() {
|
|
9669
|
+
const all = [];
|
|
9670
|
+
for (const ctx of this.sessionContexts.values()) {
|
|
9671
|
+
all.push(...ctx.items);
|
|
9672
|
+
}
|
|
9673
|
+
return all;
|
|
9674
|
+
}
|
|
9675
|
+
/**
|
|
9676
|
+
* Clear session context (for testing / cleanup).
|
|
9677
|
+
*/
|
|
9678
|
+
clearSession(conversationId) {
|
|
9679
|
+
this.sessionContexts.delete(conversationId);
|
|
9680
|
+
}
|
|
9681
|
+
/**
|
|
9682
|
+
* Get capture engine configuration.
|
|
9683
|
+
*/
|
|
9684
|
+
getConfig() {
|
|
9685
|
+
return { ...this.config };
|
|
9686
|
+
}
|
|
9687
|
+
// ---------------------------------------------------------------------------
|
|
9688
|
+
// Private
|
|
9689
|
+
// ---------------------------------------------------------------------------
|
|
9690
|
+
async storeSessionContext(conversationId, items, instructions) {
|
|
9691
|
+
let ctx = this.sessionContexts.get(conversationId);
|
|
9692
|
+
if (!ctx) {
|
|
9693
|
+
ctx = {
|
|
9694
|
+
conversationId,
|
|
9695
|
+
startedAt: nowIso(),
|
|
9696
|
+
items: [],
|
|
9697
|
+
explicitInstructions: []
|
|
9698
|
+
};
|
|
9699
|
+
this.sessionContexts.set(conversationId, ctx);
|
|
9700
|
+
}
|
|
9701
|
+
ctx.items.push(...items);
|
|
9702
|
+
ctx.explicitInstructions.push(...instructions);
|
|
9703
|
+
try {
|
|
9704
|
+
const stateKey = `${CAPTURE_STATE_KEY}:${conversationId}`;
|
|
9705
|
+
const existing = store.get(stateKey);
|
|
9706
|
+
let prior = [];
|
|
9707
|
+
if (existing) {
|
|
9708
|
+
try {
|
|
9709
|
+
prior = JSON.parse(existing);
|
|
9710
|
+
} catch {
|
|
9711
|
+
}
|
|
9712
|
+
}
|
|
9713
|
+
store.set(stateKey, JSON.stringify([...prior, ...items]));
|
|
9714
|
+
} catch {
|
|
9715
|
+
}
|
|
9716
|
+
}
|
|
9717
|
+
};
|
|
9718
|
+
var captureEngine = new CaptureEngine();
|
|
9719
|
+
async function captureConversation(messages, options) {
|
|
9720
|
+
return captureEngine.captureConversation(messages, options);
|
|
9721
|
+
}
|
|
9722
|
+
__name(captureConversation, "captureConversation");
|
|
9723
|
+
async function captureTurn(text, options) {
|
|
9724
|
+
return captureEngine.captureTurn(text, options);
|
|
9725
|
+
}
|
|
9726
|
+
__name(captureTurn, "captureTurn");
|
|
9727
|
+
|
|
8458
9728
|
// core/memory/index.ts
|
|
8459
9729
|
init_detection_events();
|
|
8460
9730
|
init_detection_journal();
|
|
@@ -8564,7 +9834,7 @@ var memory = {
|
|
|
8564
9834
|
*/
|
|
8565
9835
|
async clear() {
|
|
8566
9836
|
await entries.clearEntries();
|
|
8567
|
-
store.remove("__dotmem_acquired_knowledge_state__");
|
|
9837
|
+
store$1.remove("__dotmem_acquired_knowledge_state__");
|
|
8568
9838
|
await resetKnowledgeRuntimeCaches();
|
|
8569
9839
|
resetBrainPathCache();
|
|
8570
9840
|
resetPolicyStoreCache();
|
|
@@ -8642,6 +9912,25 @@ var memory = {
|
|
|
8642
9912
|
async getSeedId() {
|
|
8643
9913
|
return SEED_ID;
|
|
8644
9914
|
}
|
|
9915
|
+
},
|
|
9916
|
+
/** Automatic conversational capture engine (Phase 2 — Workstream B). */
|
|
9917
|
+
capture: {
|
|
9918
|
+
engine: captureEngine,
|
|
9919
|
+
async conversation(messages, options) {
|
|
9920
|
+
return captureConversation(messages, options);
|
|
9921
|
+
},
|
|
9922
|
+
async turn(text, options) {
|
|
9923
|
+
return captureTurn(text, options);
|
|
9924
|
+
},
|
|
9925
|
+
async getItems(conversationId) {
|
|
9926
|
+
return captureEngine.getCapturedItems(conversationId);
|
|
9927
|
+
},
|
|
9928
|
+
async getAllItems() {
|
|
9929
|
+
return captureEngine.getAllCapturedItems();
|
|
9930
|
+
},
|
|
9931
|
+
clearSession(conversationId) {
|
|
9932
|
+
captureEngine.clearSession(conversationId);
|
|
9933
|
+
}
|
|
8645
9934
|
}
|
|
8646
9935
|
};
|
|
8647
9936
|
|