@equationalapplications/core-llm-wiki 4.14.0 → 4.14.1
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/README.md +12 -0
- package/dist/{chunk-6FWG2DG4.mjs → chunk-24ANTHZB.mjs} +77 -23
- package/dist/chunk-24ANTHZB.mjs.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +84 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -4
- package/dist/index.mjs.map +1 -1
- package/dist/{testing-CDIDE4Jd.d.mts → testing-DW1qufP0.d.mts} +15 -1
- package/dist/{testing-CDIDE4Jd.d.ts → testing-DW1qufP0.d.ts} +15 -1
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +290 -236
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +1 -1
- package/package.json +2 -2
- package/dist/chunk-6FWG2DG4.mjs.map +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MemoryBundle, F as FormatContextOptions, a as MemoryDump, b as FormattedMemoryDump, R as ReadOptions, S as SQLiteAdapter, W as WikiOptions, c as WikiMemory } from './testing-
|
|
2
|
-
export { E as EntityStatus, d as ExtractedFact, e as ExtractedTask, H as HOOK_TIMEOUT_MARKER, L as LLMProvider, P as PromptOverrides, f as PromptService, g as PrunePartialFailureError, V as VectorRanker, h as VectorRankerFallback, i as VectorRankerRankArgs, j as VectorRankerSemanticResult, k as WikiBusyError, l as WikiBusyOperation, m as WikiCheckpoint, n as WikiConfig, o as WikiEvent, p as WikiFact, q as WikiMemoryTestAccess, r as WikiOutboxEvent, s as WikiTask } from './testing-
|
|
1
|
+
import { M as MemoryBundle, F as FormatContextOptions, a as MemoryDump, b as FormattedMemoryDump, R as ReadOptions, S as SQLiteAdapter, W as WikiOptions, c as WikiMemory } from './testing-DW1qufP0.mjs';
|
|
2
|
+
export { E as EntityStatus, d as ExtractedFact, e as ExtractedTask, H as HOOK_TIMEOUT_MARKER, L as LLMProvider, P as PromptOverrides, f as PromptService, g as PrunePartialFailureError, V as VectorRanker, h as VectorRankerFallback, i as VectorRankerRankArgs, j as VectorRankerSemanticResult, k as WikiBusyError, l as WikiBusyOperation, m as WikiCheckpoint, n as WikiConfig, o as WikiEvent, p as WikiFact, q as WikiMemoryTestAccess, r as WikiOutboxEvent, s as WikiTask } from './testing-DW1qufP0.mjs';
|
|
3
3
|
import { OkfFile } from '@equationalapplications/core-okf';
|
|
4
4
|
import 'minisearch';
|
|
5
5
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MemoryBundle, F as FormatContextOptions, a as MemoryDump, b as FormattedMemoryDump, R as ReadOptions, S as SQLiteAdapter, W as WikiOptions, c as WikiMemory } from './testing-
|
|
2
|
-
export { E as EntityStatus, d as ExtractedFact, e as ExtractedTask, H as HOOK_TIMEOUT_MARKER, L as LLMProvider, P as PromptOverrides, f as PromptService, g as PrunePartialFailureError, V as VectorRanker, h as VectorRankerFallback, i as VectorRankerRankArgs, j as VectorRankerSemanticResult, k as WikiBusyError, l as WikiBusyOperation, m as WikiCheckpoint, n as WikiConfig, o as WikiEvent, p as WikiFact, q as WikiMemoryTestAccess, r as WikiOutboxEvent, s as WikiTask } from './testing-
|
|
1
|
+
import { M as MemoryBundle, F as FormatContextOptions, a as MemoryDump, b as FormattedMemoryDump, R as ReadOptions, S as SQLiteAdapter, W as WikiOptions, c as WikiMemory } from './testing-DW1qufP0.js';
|
|
2
|
+
export { E as EntityStatus, d as ExtractedFact, e as ExtractedTask, H as HOOK_TIMEOUT_MARKER, L as LLMProvider, P as PromptOverrides, f as PromptService, g as PrunePartialFailureError, V as VectorRanker, h as VectorRankerFallback, i as VectorRankerRankArgs, j as VectorRankerSemanticResult, k as WikiBusyError, l as WikiBusyOperation, m as WikiCheckpoint, n as WikiConfig, o as WikiEvent, p as WikiFact, q as WikiMemoryTestAccess, r as WikiOutboxEvent, s as WikiTask } from './testing-DW1qufP0.js';
|
|
3
3
|
import { OkfFile } from '@equationalapplications/core-okf';
|
|
4
4
|
import 'minisearch';
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -926,7 +926,9 @@ function generateId(prefix = "") {
|
|
|
926
926
|
crypto.getRandomValues(bytes);
|
|
927
927
|
return prefix + Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("").substring(0, 24);
|
|
928
928
|
}
|
|
929
|
-
|
|
929
|
+
throw new Error(
|
|
930
|
+
"generateId: no cryptographically secure random source available (crypto.randomUUID and crypto.getRandomValues are both missing)."
|
|
931
|
+
);
|
|
930
932
|
}
|
|
931
933
|
|
|
932
934
|
// src/repositories/OutboxRepository.ts
|
|
@@ -1711,6 +1713,20 @@ var JobManager = class {
|
|
|
1711
1713
|
this.activeMaintenanceJobs = /* @__PURE__ */ new Set();
|
|
1712
1714
|
this.activeIngestJobs = /* @__PURE__ */ new Map();
|
|
1713
1715
|
this.statusSubscribers = /* @__PURE__ */ new Map();
|
|
1716
|
+
/**
|
|
1717
|
+
* Lookup table for acquireLock/releaseLock's dynamic-dispatch branch.
|
|
1718
|
+
* Excludes 'ingest' | 'global_reembed' | 'global_import', which those
|
|
1719
|
+
* methods already handle via explicit if/else branches before reaching
|
|
1720
|
+
* this table.
|
|
1721
|
+
*/
|
|
1722
|
+
this.lockKeyFns = {
|
|
1723
|
+
prune: (id) => this._pruneKey(id),
|
|
1724
|
+
librarian: (id) => this._librarianKey(id),
|
|
1725
|
+
heal: (id) => this._healKey(id),
|
|
1726
|
+
reembed: (id) => this._reembedKey(id),
|
|
1727
|
+
import: (id) => this._importKey(id),
|
|
1728
|
+
forget: (id) => this._forgetKey(id)
|
|
1729
|
+
};
|
|
1714
1730
|
}
|
|
1715
1731
|
_pruneKey(entityId) {
|
|
1716
1732
|
return `${this.prefix}:${entityId}:prune`;
|
|
@@ -1860,9 +1876,7 @@ var JobManager = class {
|
|
|
1860
1876
|
} else if (operation === "global_import") {
|
|
1861
1877
|
this.activeMaintenanceJobs.add(this._globalImportKey());
|
|
1862
1878
|
} else {
|
|
1863
|
-
|
|
1864
|
-
const keyFn = this[keyFnName];
|
|
1865
|
-
this.activeMaintenanceJobs.add(keyFn.call(this, entityId));
|
|
1879
|
+
this.activeMaintenanceJobs.add(this.lockKeyFns[operation](entityId));
|
|
1866
1880
|
}
|
|
1867
1881
|
this._notifyStatusSubscribers(entityId);
|
|
1868
1882
|
}
|
|
@@ -1874,9 +1888,7 @@ var JobManager = class {
|
|
|
1874
1888
|
} else if (operation === "global_import") {
|
|
1875
1889
|
this.activeMaintenanceJobs.delete(this._globalImportKey());
|
|
1876
1890
|
} else {
|
|
1877
|
-
|
|
1878
|
-
const keyFn = this[keyFnName];
|
|
1879
|
-
this.activeMaintenanceJobs.delete(keyFn.call(this, entityId));
|
|
1891
|
+
this.activeMaintenanceJobs.delete(this.lockKeyFns[operation](entityId));
|
|
1880
1892
|
}
|
|
1881
1893
|
this._notifyStatusSubscribers(entityId);
|
|
1882
1894
|
}
|
|
@@ -2826,6 +2838,9 @@ var MaintenanceService = class {
|
|
|
2826
2838
|
};
|
|
2827
2839
|
|
|
2828
2840
|
// src/services/ImportExportService.ts
|
|
2841
|
+
var MAX_EMBEDDING_BLOB_BYTES = 32 * 1024;
|
|
2842
|
+
var IMPORT_TITLE_MAX = 500;
|
|
2843
|
+
var IMPORT_BODY_MAX = 8e3;
|
|
2829
2844
|
var ImportExportService = class {
|
|
2830
2845
|
constructor(db, entryRepo, taskRepo, eventRepo, metadataRepo, searchService, jobManager, embeddingService) {
|
|
2831
2846
|
this.db = db;
|
|
@@ -2907,6 +2922,7 @@ var ImportExportService = class {
|
|
|
2907
2922
|
const factsWithPreservedBlob = /* @__PURE__ */ new Map();
|
|
2908
2923
|
const preservedBlobDims = /* @__PURE__ */ new Set();
|
|
2909
2924
|
const softDeletedFactIds = [];
|
|
2925
|
+
const clippedTextByFactId = /* @__PURE__ */ new Map();
|
|
2910
2926
|
await this.db.withTransactionAsync(async (tx) => {
|
|
2911
2927
|
if (!merge) {
|
|
2912
2928
|
const deletedLiveFactIds = await this.entryRepo.findIdsBySource(
|
|
@@ -2943,21 +2959,32 @@ var ImportExportService = class {
|
|
|
2943
2959
|
const rawBlobRaw = fact.embedding_blob;
|
|
2944
2960
|
let rawBlob = null;
|
|
2945
2961
|
if (rawBlobRaw instanceof Uint8Array) {
|
|
2946
|
-
|
|
2962
|
+
if (rawBlobRaw.byteLength <= MAX_EMBEDDING_BLOB_BYTES) {
|
|
2963
|
+
rawBlob = rawBlobRaw;
|
|
2964
|
+
}
|
|
2947
2965
|
} else if (rawBlobRaw !== null && rawBlobRaw !== void 0 && typeof rawBlobRaw === "object") {
|
|
2948
2966
|
const obj = rawBlobRaw;
|
|
2949
2967
|
if (obj["type"] === "Buffer" && Array.isArray(obj["data"])) {
|
|
2950
|
-
|
|
2968
|
+
const data = obj["data"];
|
|
2969
|
+
if (data.length <= MAX_EMBEDDING_BLOB_BYTES) {
|
|
2970
|
+
rawBlob = new Uint8Array(data);
|
|
2971
|
+
}
|
|
2951
2972
|
} else if (!Array.isArray(rawBlobRaw)) {
|
|
2952
2973
|
const entries = Object.keys(obj);
|
|
2953
2974
|
if (entries.length > 0 && entries.every((k) => /^\d+$/.test(k))) {
|
|
2954
2975
|
const len = entries.length;
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2976
|
+
if (len <= MAX_EMBEDDING_BLOB_BYTES) {
|
|
2977
|
+
rawBlob = new Uint8Array(len);
|
|
2978
|
+
for (let i = 0; i < len; i++) {
|
|
2979
|
+
rawBlob[i] = obj[String(i)] ?? 0;
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2958
2982
|
}
|
|
2959
2983
|
}
|
|
2960
2984
|
}
|
|
2985
|
+
if (rawBlob !== null && rawBlob.byteLength > MAX_EMBEDDING_BLOB_BYTES) {
|
|
2986
|
+
rawBlob = null;
|
|
2987
|
+
}
|
|
2961
2988
|
let blobData = null;
|
|
2962
2989
|
if (rawBlob !== null && rawBlob.byteLength > 0 && rawBlob.byteLength % 4 === 0) {
|
|
2963
2990
|
const copy = new ArrayBuffer(rawBlob.byteLength);
|
|
@@ -2987,11 +3014,14 @@ var ImportExportService = class {
|
|
|
2987
3014
|
}
|
|
2988
3015
|
if (merge && safeUpdatedAt <= existing.updated_at) continue;
|
|
2989
3016
|
}
|
|
3017
|
+
const safeTitle = clip(String(fact.title ?? ""), IMPORT_TITLE_MAX);
|
|
3018
|
+
const safeBody = clip(String(fact.body ?? ""), IMPORT_BODY_MAX);
|
|
3019
|
+
clippedTextByFactId.set(fact.id, { title: safeTitle, body: safeBody });
|
|
2990
3020
|
const factObj = {
|
|
2991
3021
|
id: fact.id,
|
|
2992
3022
|
entity_id: entityId,
|
|
2993
|
-
title:
|
|
2994
|
-
body:
|
|
3023
|
+
title: safeTitle,
|
|
3024
|
+
body: safeBody,
|
|
2995
3025
|
tags: Array.isArray(fact.tags) ? fact.tags : [],
|
|
2996
3026
|
confidence: fact.confidence,
|
|
2997
3027
|
source_type: sourceType,
|
|
@@ -3079,11 +3109,12 @@ var ImportExportService = class {
|
|
|
3079
3109
|
await this.searchService.sync(entityId);
|
|
3080
3110
|
for (const fact of bundle.facts) {
|
|
3081
3111
|
if (!fact.deleted_at && upsertedFactIds.has(fact.id) && !factsWithPreservedBlob.has(fact.id)) {
|
|
3112
|
+
const clipped = clippedTextByFactId.get(fact.id);
|
|
3082
3113
|
const embedded = await this.embeddingService.embedFact({
|
|
3083
3114
|
id: fact.id,
|
|
3084
3115
|
entity_id: entityId,
|
|
3085
|
-
title: fact.title,
|
|
3086
|
-
body: fact.body,
|
|
3116
|
+
title: clipped?.title ?? fact.title,
|
|
3117
|
+
body: clipped?.body ?? fact.body,
|
|
3087
3118
|
tags: Array.isArray(fact.tags) || typeof fact.tags === "string" ? fact.tags : []
|
|
3088
3119
|
});
|
|
3089
3120
|
if (!embedded) {
|
|
@@ -3183,7 +3214,7 @@ var ImportExportService = class {
|
|
|
3183
3214
|
}
|
|
3184
3215
|
_warnCrossEntityCollision(type, id, existingEntityId, targetEntityId) {
|
|
3185
3216
|
console.warn(
|
|
3186
|
-
`[WikiMemory] importDump: ${type} id
|
|
3217
|
+
`[WikiMemory] importDump: ${type} id ${JSON.stringify(id)} already belongs to entity ${JSON.stringify(existingEntityId)}; skipping for entity ${JSON.stringify(targetEntityId)}`
|
|
3187
3218
|
);
|
|
3188
3219
|
}
|
|
3189
3220
|
_normalizeImportedSourceType(raw, ctx) {
|
|
@@ -3262,7 +3293,7 @@ var EmbeddingService = class {
|
|
|
3262
3293
|
tagsStr = fact.tags;
|
|
3263
3294
|
}
|
|
3264
3295
|
}
|
|
3265
|
-
const text = `${fact.title} ${fact.body} ${tagsStr}`.trim();
|
|
3296
|
+
const text = clip(`${fact.title} ${fact.body} ${tagsStr}`.trim(), 16e3);
|
|
3266
3297
|
try {
|
|
3267
3298
|
const vector = await embedFn(text);
|
|
3268
3299
|
if (vector.length === 0 || !vector.every((v) => typeof v === "number" && isFinite(v))) {
|
|
@@ -3876,15 +3907,38 @@ var RetrievalService = class {
|
|
|
3876
3907
|
|
|
3877
3908
|
// src/services/WriteService.ts
|
|
3878
3909
|
var WriteService = class {
|
|
3879
|
-
constructor(db, options, eventRepo, metadataRepo, jobManager, maintenanceService) {
|
|
3910
|
+
constructor(db, options, entryRepo, eventRepo, metadataRepo, jobManager, maintenanceService) {
|
|
3880
3911
|
this.db = db;
|
|
3881
3912
|
this.options = options;
|
|
3913
|
+
this.entryRepo = entryRepo;
|
|
3882
3914
|
this.eventRepo = eventRepo;
|
|
3883
3915
|
this.metadataRepo = metadataRepo;
|
|
3884
3916
|
this.jobManager = jobManager;
|
|
3885
3917
|
this.maintenanceService = maintenanceService;
|
|
3886
3918
|
}
|
|
3887
3919
|
async write(entityId, event) {
|
|
3920
|
+
if (typeof entityId !== "string" || entityId.length === 0 || entityId.length > 200 || entityId.includes("\0")) {
|
|
3921
|
+
throw new TypeError(
|
|
3922
|
+
`Invalid entityId: must be a non-empty string at most 200 chars with no null bytes; got ${JSON.stringify(entityId)}.`
|
|
3923
|
+
);
|
|
3924
|
+
}
|
|
3925
|
+
if (event === null || typeof event !== "object" || Array.isArray(event)) {
|
|
3926
|
+
throw new TypeError("Invalid event: must be a non-null object.");
|
|
3927
|
+
}
|
|
3928
|
+
if (typeof event.summary !== "string") {
|
|
3929
|
+
throw new TypeError("Invalid event.summary: must be a string.");
|
|
3930
|
+
}
|
|
3931
|
+
const summary = clip(event.summary, 4e3);
|
|
3932
|
+
let relatedEntryId = null;
|
|
3933
|
+
const rawRelatedEntryId = event.related_entry_id;
|
|
3934
|
+
if (rawRelatedEntryId != null && rawRelatedEntryId !== "") {
|
|
3935
|
+
if (typeof rawRelatedEntryId !== "string" || rawRelatedEntryId.length > 200 || rawRelatedEntryId.includes("\0")) {
|
|
3936
|
+
relatedEntryId = null;
|
|
3937
|
+
} else {
|
|
3938
|
+
const existing = await this.entryRepo.findByIds([rawRelatedEntryId], [entityId]);
|
|
3939
|
+
relatedEntryId = existing.length > 0 ? rawRelatedEntryId : null;
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3888
3942
|
const id = generateId("evt_");
|
|
3889
3943
|
const now = Date.now();
|
|
3890
3944
|
let eventType = event.event_type;
|
|
@@ -3895,8 +3949,8 @@ var WriteService = class {
|
|
|
3895
3949
|
id,
|
|
3896
3950
|
entity_id: entityId,
|
|
3897
3951
|
event_type: eventType,
|
|
3898
|
-
summary
|
|
3899
|
-
related_entry_id:
|
|
3952
|
+
summary,
|
|
3953
|
+
related_entry_id: relatedEntryId,
|
|
3900
3954
|
created_at: now
|
|
3901
3955
|
};
|
|
3902
3956
|
let shouldRunLibrarian = false;
|
|
@@ -3957,6 +4011,7 @@ var WriteService = class {
|
|
|
3957
4011
|
};
|
|
3958
4012
|
|
|
3959
4013
|
// src/WikiMemory.ts
|
|
4014
|
+
var TABLE_PREFIX_PATTERN = /^[A-Za-z][A-Za-z0-9_]{0,30}_$/;
|
|
3960
4015
|
var _testAccessNonTestEnvWarned;
|
|
3961
4016
|
var WikiMemory = class {
|
|
3962
4017
|
constructor(db, options) {
|
|
@@ -3964,7 +4019,12 @@ var WikiMemory = class {
|
|
|
3964
4019
|
__privateAdd(this, _testAccessNonTestEnvWarned, false);
|
|
3965
4020
|
this.db = db;
|
|
3966
4021
|
this.options = options;
|
|
3967
|
-
this.prefix = options.config?.tablePrefix
|
|
4022
|
+
this.prefix = options.config?.tablePrefix ?? "llm_wiki_";
|
|
4023
|
+
if (!TABLE_PREFIX_PATTERN.test(this.prefix)) {
|
|
4024
|
+
throw new Error(
|
|
4025
|
+
`Invalid tablePrefix: ${JSON.stringify(this.prefix)}. Must match ${TABLE_PREFIX_PATTERN} (letter, then alphanumeric/underscore, ending in "_", max 32 chars total).`
|
|
4026
|
+
);
|
|
4027
|
+
}
|
|
3968
4028
|
this.outboxRepo = new OutboxRepository(db, this.prefix, !!options.config?.enableOutbox);
|
|
3969
4029
|
this.entryRepo = new EntryRepository(db, this.prefix, this.outboxRepo);
|
|
3970
4030
|
this.taskRepo = new TaskRepository(db, this.prefix, this.outboxRepo);
|
|
@@ -4018,6 +4078,7 @@ var WikiMemory = class {
|
|
|
4018
4078
|
this.writeService = new WriteService(
|
|
4019
4079
|
this.db,
|
|
4020
4080
|
this.options,
|
|
4081
|
+
this.entryRepo,
|
|
4021
4082
|
this.eventRepo,
|
|
4022
4083
|
this.metadataRepo,
|
|
4023
4084
|
this.jobManager,
|
|
@@ -4096,7 +4157,7 @@ var WikiMemory = class {
|
|
|
4096
4157
|
async hasChanged(entityId, sourceRef, sourceHash) {
|
|
4097
4158
|
const normalizedRef = normalizeSourceRef(sourceRef);
|
|
4098
4159
|
if (!normalizedRef) {
|
|
4099
|
-
throw new Error(`Invalid sourceRef:
|
|
4160
|
+
throw new Error(`Invalid sourceRef: ${JSON.stringify(sourceRef)}`);
|
|
4100
4161
|
}
|
|
4101
4162
|
const normalizedHash = normalizeSourceHash(sourceHash);
|
|
4102
4163
|
if (!normalizedHash) {
|