@theokit/sdk-memory 0.3.3 → 0.4.0
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/CHANGELOG.md +23 -0
- package/dist/index.cjs +80 -130
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +30 -108
- package/dist/index.js.map +1 -1
- package/dist/internal/store/markdown-store.d.ts +24 -32
- package/dist/internal/store/markdown-store.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { mkdir,
|
|
1
|
+
import { mkdir, readdir, readFile, stat, access, unlink } from 'fs/promises';
|
|
2
2
|
import { join, resolve, relative } from 'path';
|
|
3
3
|
import { Security } from '@theokit/sdk';
|
|
4
|
-
import { replaceFileAtomic,
|
|
5
|
-
import {
|
|
4
|
+
import { replaceFileAtomic, atomicWriteJson, withCwdMutex, openSqliteResilient, sanitizeFts5Query } from '@theokit/sdk/persistence';
|
|
5
|
+
import { notesDir, memoryDir, readFactsFromMarkdown, memoryMdPath, appendFactToMarkdown } from '@theokit/sdk/internal/memory-store';
|
|
6
|
+
export { appendFact, appendFactToMarkdown, claudeProjectMemoryDir, memoryDir, memoryMdPath, memoryWriteDir, notesDir, readFacts, readFactsFromMarkdown } from '@theokit/sdk/internal/memory-store';
|
|
6
7
|
import { createHash } from 'crypto';
|
|
7
8
|
import { createOpenAiCompatibleRuntime } from '@theokit/sdk/internal/memory-adapters';
|
|
8
9
|
export { createOpenAiCompatibleRuntime } from '@theokit/sdk/internal/memory-adapters';
|
|
9
10
|
import { AuthenticationError, RateLimitError, ConfigurationError, NetworkError, UnknownAgentError } from '@theokit/sdk/errors';
|
|
11
|
+
import { sanitizeIdentifier, safePathJoin } from '@theokit/sdk/path-safety';
|
|
10
12
|
import { mkdirSync, existsSync, rmSync, renameSync } from 'fs';
|
|
11
13
|
import { createRequire } from 'module';
|
|
12
14
|
|
|
@@ -238,55 +240,6 @@ function createInMemoryMarkdownProvider() {
|
|
|
238
240
|
}
|
|
239
241
|
};
|
|
240
242
|
}
|
|
241
|
-
function redactSecrets(text, opts) {
|
|
242
|
-
return Security.redact(text, opts);
|
|
243
|
-
}
|
|
244
|
-
function legacyMemoryJsonPath(cwd, config) {
|
|
245
|
-
if (config.storePath !== void 0) {
|
|
246
|
-
return resolve(cwd, config.storePath);
|
|
247
|
-
}
|
|
248
|
-
const namespace = sanitizeIdentifier(config.namespace ?? "default");
|
|
249
|
-
const scope = sanitizeIdentifier(config.scope ?? "agent", { maxLen: 16 });
|
|
250
|
-
const userId = sanitizeIdentifier(config.userId ?? "default");
|
|
251
|
-
return safePathJoin(cwd, ".theokit", "memory", namespace, `${scope}-${userId}.json`);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// src/internal/store/markdown-store.ts
|
|
255
|
-
var MEMORY_MD_HEADER = "# Memory\n\n> Auto-managed by @theokit/sdk. Edit freely \u2014 the SDK reads from here.\n";
|
|
256
|
-
var FACTS_HEADING = "## Facts";
|
|
257
|
-
function memoryDir(cwd) {
|
|
258
|
-
return join(cwd, ".theokit", "memory");
|
|
259
|
-
}
|
|
260
|
-
function memoryMdPath(cwd) {
|
|
261
|
-
return join(memoryDir(cwd), "MEMORY.md");
|
|
262
|
-
}
|
|
263
|
-
function notesDir(cwd) {
|
|
264
|
-
return join(memoryDir(cwd), "notes");
|
|
265
|
-
}
|
|
266
|
-
async function readFactsFromMarkdown(cwd) {
|
|
267
|
-
let raw;
|
|
268
|
-
try {
|
|
269
|
-
raw = await readFile(memoryMdPath(cwd), "utf8");
|
|
270
|
-
} catch {
|
|
271
|
-
return [];
|
|
272
|
-
}
|
|
273
|
-
return parseFactsSection(raw);
|
|
274
|
-
}
|
|
275
|
-
function appendFactToMarkdown(cwd, fact) {
|
|
276
|
-
return withCwdMutex(memoryDir(cwd), async () => {
|
|
277
|
-
const path = memoryMdPath(cwd);
|
|
278
|
-
let raw = "";
|
|
279
|
-
try {
|
|
280
|
-
raw = await readFile(path, "utf8");
|
|
281
|
-
} catch {
|
|
282
|
-
raw = "";
|
|
283
|
-
}
|
|
284
|
-
const sanitized = redactSecrets(fact.text);
|
|
285
|
-
const next = insertFactBullet(raw, sanitized);
|
|
286
|
-
await mkdir(memoryDir(cwd), { recursive: true });
|
|
287
|
-
await replaceFileAtomic(path, next);
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
243
|
async function listNotes(cwd) {
|
|
291
244
|
let entries = [];
|
|
292
245
|
try {
|
|
@@ -296,51 +249,6 @@ async function listNotes(cwd) {
|
|
|
296
249
|
}
|
|
297
250
|
return entries.filter((name) => name.endsWith(".md")).map((name) => ({ slug: name.replace(/\.md$/, ""), path: join(notesDir(cwd), name) }));
|
|
298
251
|
}
|
|
299
|
-
function parseFactsSection(raw) {
|
|
300
|
-
const idx = raw.indexOf(FACTS_HEADING);
|
|
301
|
-
if (idx === -1) return [];
|
|
302
|
-
const tail = raw.slice(idx + FACTS_HEADING.length);
|
|
303
|
-
const nextHeading = tail.search(/\n#{1,2}\s/);
|
|
304
|
-
const block = nextHeading === -1 ? tail : tail.slice(0, nextHeading);
|
|
305
|
-
return block.split("\n").map((line) => line.trim()).filter((line) => line.startsWith("- ")).map((line) => ({ text: line.slice(2).trim() }));
|
|
306
|
-
}
|
|
307
|
-
function insertFactBullet(raw, fact) {
|
|
308
|
-
const bullet = `- ${fact}`;
|
|
309
|
-
if (raw.length === 0) {
|
|
310
|
-
return `${MEMORY_MD_HEADER}
|
|
311
|
-
${FACTS_HEADING}
|
|
312
|
-
|
|
313
|
-
${bullet}
|
|
314
|
-
`;
|
|
315
|
-
}
|
|
316
|
-
const idx = raw.indexOf(FACTS_HEADING);
|
|
317
|
-
if (idx === -1) {
|
|
318
|
-
const sep = raw.endsWith("\n") ? "" : "\n";
|
|
319
|
-
return `${raw}${sep}
|
|
320
|
-
${FACTS_HEADING}
|
|
321
|
-
|
|
322
|
-
${bullet}
|
|
323
|
-
`;
|
|
324
|
-
}
|
|
325
|
-
const after = idx + FACTS_HEADING.length;
|
|
326
|
-
const nextHeading = raw.slice(after).search(/\n#{1,2}\s/);
|
|
327
|
-
if (nextHeading === -1) {
|
|
328
|
-
const trailing = raw.endsWith("\n") ? "" : "\n";
|
|
329
|
-
return `${raw}${trailing}${bullet}
|
|
330
|
-
`;
|
|
331
|
-
}
|
|
332
|
-
const insertAt = after + nextHeading;
|
|
333
|
-
return `${raw.slice(0, insertAt)}
|
|
334
|
-
${bullet}${raw.slice(insertAt)}`;
|
|
335
|
-
}
|
|
336
|
-
async function readFacts(cwd, config) {
|
|
337
|
-
if (!config.enabled) return [];
|
|
338
|
-
return readFactsFromMarkdown(cwd);
|
|
339
|
-
}
|
|
340
|
-
async function appendFact(cwd, config, fact) {
|
|
341
|
-
if (!config.enabled) return;
|
|
342
|
-
await appendFactToMarkdown(cwd, fact);
|
|
343
|
-
}
|
|
344
252
|
|
|
345
253
|
// src/internal/store/transcript-store.ts
|
|
346
254
|
async function persistActiveMemoryTranscript(cwd, transcript) {
|
|
@@ -949,6 +857,20 @@ var MEMORY_EMBEDDING_ADAPTERS = {
|
|
|
949
857
|
jina: jinaMemoryEmbeddingProviderAdapter,
|
|
950
858
|
gemini: geminiMemoryEmbeddingProviderAdapter
|
|
951
859
|
};
|
|
860
|
+
function redactSecrets(text, opts) {
|
|
861
|
+
return Security.redact(text, opts);
|
|
862
|
+
}
|
|
863
|
+
function legacyMemoryJsonPath(cwd, config) {
|
|
864
|
+
if (config.storePath !== void 0) {
|
|
865
|
+
return resolve(cwd, config.storePath);
|
|
866
|
+
}
|
|
867
|
+
const namespace = sanitizeIdentifier(config.namespace ?? "default");
|
|
868
|
+
const scope = sanitizeIdentifier(config.scope ?? "agent", { maxLen: 16 });
|
|
869
|
+
const userId = sanitizeIdentifier(config.userId ?? "default");
|
|
870
|
+
return safePathJoin(cwd, ".theokit", "memory", namespace, `${scope}-${userId}.json`);
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
// src/internal/adapter-http-error.ts
|
|
952
874
|
var RAW_MAX_BYTES = 2048;
|
|
953
875
|
function parseRetryAfter(headers) {
|
|
954
876
|
if (headers === void 0) return void 0;
|
|
@@ -1037,7 +959,7 @@ function mapOpenAiStatusToCode(status, body) {
|
|
|
1037
959
|
function formatMessage(providerId, status, code) {
|
|
1038
960
|
return `${providerId} API error: ${code} (HTTP ${status})`;
|
|
1039
961
|
}
|
|
1040
|
-
var
|
|
962
|
+
var FACTS_HEADING = "## Facts";
|
|
1041
963
|
function createCategorizedMemory(options) {
|
|
1042
964
|
const { root, categories } = options;
|
|
1043
965
|
validateCategories(categories);
|
|
@@ -1111,7 +1033,7 @@ function header(category) {
|
|
|
1111
1033
|
category: ${category}
|
|
1112
1034
|
---
|
|
1113
1035
|
|
|
1114
|
-
${
|
|
1036
|
+
${FACTS_HEADING}
|
|
1115
1037
|
`;
|
|
1116
1038
|
}
|
|
1117
1039
|
async function readFileOrEmpty(path) {
|
|
@@ -1135,24 +1057,24 @@ function decodeFact(text) {
|
|
|
1135
1057
|
);
|
|
1136
1058
|
}
|
|
1137
1059
|
function parseFactBullets(raw) {
|
|
1138
|
-
const idx = raw.indexOf(
|
|
1060
|
+
const idx = raw.indexOf(FACTS_HEADING);
|
|
1139
1061
|
if (idx === -1) return [];
|
|
1140
|
-
const tail = raw.slice(idx +
|
|
1062
|
+
const tail = raw.slice(idx + FACTS_HEADING.length);
|
|
1141
1063
|
const nextHeading = tail.search(/\n#{1,2}\s/);
|
|
1142
1064
|
const block = nextHeading === -1 ? tail : tail.slice(0, nextHeading);
|
|
1143
1065
|
return block.split("\n").map((line) => line.trim()).filter((line) => line.startsWith("- ")).map((line) => line.slice(2).trim());
|
|
1144
1066
|
}
|
|
1145
1067
|
function appendBullet(raw, text) {
|
|
1146
1068
|
const bullet = `- ${text}`;
|
|
1147
|
-
const idx = raw.indexOf(
|
|
1069
|
+
const idx = raw.indexOf(FACTS_HEADING);
|
|
1148
1070
|
if (idx === -1) {
|
|
1149
1071
|
const sep = raw.endsWith("\n") ? "" : "\n";
|
|
1150
|
-
return `${raw}${sep}${
|
|
1072
|
+
return `${raw}${sep}${FACTS_HEADING}
|
|
1151
1073
|
|
|
1152
1074
|
${bullet}
|
|
1153
1075
|
`;
|
|
1154
1076
|
}
|
|
1155
|
-
const after = idx +
|
|
1077
|
+
const after = idx + FACTS_HEADING.length;
|
|
1156
1078
|
const nextHeading = raw.slice(after).search(/\n#{1,2}\s/);
|
|
1157
1079
|
if (nextHeading === -1) {
|
|
1158
1080
|
const trailing = raw.endsWith("\n") ? "" : "\n";
|
|
@@ -1343,10 +1265,10 @@ async function runInner(options) {
|
|
|
1343
1265
|
}
|
|
1344
1266
|
async function writeConsolidatedNotes(cwd, clusters, timestampMs) {
|
|
1345
1267
|
if (clusters.length === 0) return 0;
|
|
1346
|
-
const
|
|
1347
|
-
await mkdir(
|
|
1268
|
+
const notesDir3 = join(memoryDir(cwd), "notes");
|
|
1269
|
+
await mkdir(notesDir3, { recursive: true });
|
|
1348
1270
|
const isoSlug = new Date(timestampMs).toISOString().replace(/[^\dT]/g, "-");
|
|
1349
|
-
const file = join(
|
|
1271
|
+
const file = join(notesDir3, `dreamed-${isoSlug}.md`);
|
|
1350
1272
|
const body = deepPhase(clusters, timestampMs);
|
|
1351
1273
|
await replaceFileAtomic(file, body);
|
|
1352
1274
|
return 1;
|
|
@@ -2525,6 +2447,6 @@ function isPathInside(root, candidate) {
|
|
|
2525
2447
|
return candidate === root || candidate.startsWith(normalizedRoot);
|
|
2526
2448
|
}
|
|
2527
2449
|
|
|
2528
|
-
export { ActiveMemoryCache, CircuitBreaker, DEFAULT_AZURE_OPENAI_EMBEDDING_MODEL, DEFAULT_COHERE_EMBEDDING_MODEL, DEFAULT_DEEPINFRA_EMBEDDING_MODEL, DEFAULT_GEMINI_EMBEDDING_MODEL, DEFAULT_JINA_EMBEDDING_MODEL, DEFAULT_MEMORY_READ_LINES, DEFAULT_MISTRAL_EMBEDDING_MODEL, DEFAULT_OLLAMA_EMBEDDING_MODEL, DEFAULT_OPENAI_EMBEDDING_MODEL, DEFAULT_OPENROUTER_EMBEDDING_MODEL, DEFAULT_VOYAGE_EMBEDDING_MODEL, IndexManager, LanceIndex, LanceMemoryAdapter, MEMORY_EMBEDDING_ADAPTERS, META_KEY_DIMENSION, META_KEY_MODEL, META_KEY_PROVIDER_ID, PRAGMA_STATEMENTS, SCHEMA_STATEMENTS, VALID_BACKENDS, appendDiaryEntry,
|
|
2450
|
+
export { ActiveMemoryCache, CircuitBreaker, DEFAULT_AZURE_OPENAI_EMBEDDING_MODEL, DEFAULT_COHERE_EMBEDDING_MODEL, DEFAULT_DEEPINFRA_EMBEDDING_MODEL, DEFAULT_GEMINI_EMBEDDING_MODEL, DEFAULT_JINA_EMBEDDING_MODEL, DEFAULT_MEMORY_READ_LINES, DEFAULT_MISTRAL_EMBEDDING_MODEL, DEFAULT_OLLAMA_EMBEDDING_MODEL, DEFAULT_OPENAI_EMBEDDING_MODEL, DEFAULT_OPENROUTER_EMBEDDING_MODEL, DEFAULT_VOYAGE_EMBEDDING_MODEL, IndexManager, LanceIndex, LanceMemoryAdapter, MEMORY_EMBEDDING_ADAPTERS, META_KEY_DIMENSION, META_KEY_MODEL, META_KEY_PROVIDER_ID, PRAGMA_STATEMENTS, SCHEMA_STATEMENTS, VALID_BACKENDS, appendDiaryEntry, assertValidBackend, azureOpenAiMemoryEmbeddingProviderAdapter, buildErrorMetadata, chunkMarkdown, cohereMemoryEmbeddingProviderAdapter, createCategorizedMemory, createInMemoryMarkdownProvider, createMemoryGetTool, createMemorySearchTool, createVectorIndex, deepPhase, deepinfraMemoryEmbeddingProviderAdapter, defaultIndexPath, diaryPath, discoverSessionFiles, discoverWikiFiles, dropVectorIndex, embedMissingChunks, entryHash, geminiMemoryEmbeddingProviderAdapter, identityMatches, isLanceAvailable, isSqliteVecLoaded, jinaMemoryEmbeddingProviderAdapter, lanceStoragePath, legacyMemoryJsonPath, lightPhase, listNotes, loadSqliteVecExtension, mapOpenAICompatibleError, migrateLegacyJson, migrateSqliteToLance, mistralMemoryEmbeddingProviderAdapter, ollamaMemoryEmbeddingProviderAdapter, openAiMemoryEmbeddingProviderAdapter, openLanceIndex, openMemoryDb, openRouterMemoryEmbeddingProviderAdapter, packVector, parseRetryAfter, parseSearchOptions, persistActiveMemoryTranscript, readEmbeddingIdentity, readMemoryFileBounded, redactSecrets, remPhase, renderDiaryEntry, resetMigrationStateForTests, runActiveMemory, runDreamingSweep, sessionSummaryPath, sessionsDir, truncateRaw, upsertEmbedding, vectorSearch, voyageMemoryEmbeddingProviderAdapter, wikiDir, writeEmbeddingIdentity, writeSessionSummary };
|
|
2529
2451
|
//# sourceMappingURL=index.js.map
|
|
2530
2452
|
//# sourceMappingURL=index.js.map
|