@equationalapplications/core-llm-wiki 4.23.0 → 5.0.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/dist/{chunk-MYZJLVX4.mjs → chunk-W53E3I44.mjs} +75 -13
- package/dist/chunk-W53E3I44.mjs.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +173 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +101 -12
- package/dist/index.mjs.map +1 -1
- package/dist/{testing-CBjAuTSl.d.mts → testing-DCRNie7k.d.mts} +118 -10
- package/dist/{testing-CBjAuTSl.d.ts → testing-DCRNie7k.d.ts} +118 -10
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +72 -10
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +1 -1
- package/package.json +2 -2
- package/dist/chunk-MYZJLVX4.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { __privateAdd, MetadataRepository, EmbeddingService, SearchService, JobManager, PromptService, IngestionService, MaintenanceService, ImportExportService, RetrievalService, WriteService, __privateGet, __privateSet, normalizeSourceRef, normalizeSourceHash, entitySummaryMetaKey, generateId, BaseRepository, emptyManifest, resolveNodeType, validateInlineEdges, resolveEdgeDefinitions, normalizeTitleKey, WikiTransactionError, extractSqliteCode } from './chunk-
|
|
2
|
-
export { HOOK_TIMEOUT_MARKER, ONTOLOGY_BACKFILL_BATCH_SIZE, ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, ONTOLOGY_BACKFILL_RECHECK_MS, ONTOLOGY_BACKFILL_SYSTEM_PROMPT, PromptService, PrunePartialFailureError, WikiBusyError, WikiTransactionError, configureRandomSource, parseEmbedding, validateManifest } from './chunk-
|
|
1
|
+
import { __privateAdd, MetadataRepository, EmbeddingService, SearchService, JobManager, PromptService, IngestionService, MaintenanceService, ImportExportService, RetrievalService, WriteService, __privateGet, __privateSet, normalizeSourceRef, normalizeSourceHash, entitySummaryMetaKey, generateId, BaseRepository, emptyManifest, resolveNodeType, validateInlineEdges, resolveEdgeDefinitions, normalizeTitleKey, WikiTransactionError, extractSqliteCode } from './chunk-W53E3I44.mjs';
|
|
2
|
+
export { HEAL_BATCH_SIZE, HEAL_RECHECK_MS, HOOK_TIMEOUT_MARKER, ONTOLOGY_BACKFILL_BATCH_SIZE, ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, ONTOLOGY_BACKFILL_RECHECK_MS, ONTOLOGY_BACKFILL_SYSTEM_PROMPT, PromptService, PrunePartialFailureError, WikiBusyError, WikiTransactionError, configureRandomSource, parseEmbedding, validateManifest } from './chunk-W53E3I44.mjs';
|
|
3
3
|
import { appendRelatedSection, buildConceptDocument, buildLogMd, buildEntityIndexMd, buildRootIndexMd, isAllowedOkfPath, parseRootIndexMd, parseEntityIndexMd, parseConcept, splitRelatedSection, extractMarkdownLinks, parseLogMd, parseEventIdComment, appendEventIdComment } from '@equationalapplications/core-okf';
|
|
4
4
|
|
|
5
5
|
// src/db/schema.ts
|
|
@@ -23,7 +23,8 @@ async function setupDatabase(db, prefix) {
|
|
|
23
23
|
embedding TEXT,
|
|
24
24
|
embedding_blob BLOB,
|
|
25
25
|
okf_type TEXT,
|
|
26
|
-
ontology_checked_at INTEGER
|
|
26
|
+
ontology_checked_at INTEGER,
|
|
27
|
+
heal_checked_at INTEGER
|
|
27
28
|
);
|
|
28
29
|
|
|
29
30
|
CREATE INDEX IF NOT EXISTS ${prefix}entries_entity_idx ON ${prefix}entries(entity_id);
|
|
@@ -263,6 +264,20 @@ var MIGRATIONS = [
|
|
|
263
264
|
);
|
|
264
265
|
}
|
|
265
266
|
}
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
version: 8,
|
|
270
|
+
description: "Add heal_checked_at to entries for heal recheck cooldown",
|
|
271
|
+
run: async (db, prefix) => {
|
|
272
|
+
const cols = await db.getAllAsync(
|
|
273
|
+
`PRAGMA table_info(${prefix}entries)`
|
|
274
|
+
);
|
|
275
|
+
if (!cols.some((c) => c.name === "heal_checked_at")) {
|
|
276
|
+
await db.execAsync(
|
|
277
|
+
`ALTER TABLE ${prefix}entries ADD COLUMN heal_checked_at INTEGER`
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
266
281
|
}
|
|
267
282
|
];
|
|
268
283
|
for (let i = 1; i < MIGRATIONS.length; i++) {
|
|
@@ -604,17 +619,21 @@ var EntryRepository = class extends BaseRepository {
|
|
|
604
619
|
}
|
|
605
620
|
/**
|
|
606
621
|
* Fetch live, mutable entries for an entity — everything heal is allowed to
|
|
607
|
-
* downgrade or delete
|
|
608
|
-
*
|
|
609
|
-
*
|
|
622
|
+
* downgrade or delete — oldest first, capped at `limit`, skipping anything
|
|
623
|
+
* stamped inside the recheck cooldown (heal_checked_at > recheckCutoff).
|
|
624
|
+
*
|
|
625
|
+
* Oldest-first rather than newest-first: with a cooldown in place, newest-first
|
|
626
|
+
* would keep re-selecting recently-touched facts every pass while older ones
|
|
627
|
+
* wait indefinitely to even enter a batch.
|
|
610
628
|
*/
|
|
611
|
-
async findHealCandidatesByEntityId(entityId, tx) {
|
|
629
|
+
async findHealCandidatesByEntityId(entityId, limit, recheckCutoff, tx) {
|
|
612
630
|
const executor = this.getExecutor(tx);
|
|
613
631
|
const rows = await executor.getAllAsync(
|
|
614
632
|
`SELECT * FROM ${this.prefix}entries
|
|
615
633
|
WHERE entity_id = ? AND deleted_at IS NULL AND source_type != 'immutable_document'
|
|
616
|
-
|
|
617
|
-
|
|
634
|
+
AND (heal_checked_at IS NULL OR heal_checked_at <= ?)
|
|
635
|
+
ORDER BY updated_at ASC LIMIT ?`,
|
|
636
|
+
[entityId, recheckCutoff, limit]
|
|
618
637
|
);
|
|
619
638
|
return rows.map(mapRowToFact);
|
|
620
639
|
}
|
|
@@ -777,6 +796,10 @@ var EntryRepository = class extends BaseRepository {
|
|
|
777
796
|
/**
|
|
778
797
|
* Downgrade stale inferred entries to 'tentative'.
|
|
779
798
|
* Used by MaintenanceService.doRunHeal().
|
|
799
|
+
*
|
|
800
|
+
* Returns the ids it downgraded so the caller can fold them into
|
|
801
|
+
* {@link HealResult.downgraded} without double-counting a fact the model also
|
|
802
|
+
* downgraded in the same pass.
|
|
780
803
|
*/
|
|
781
804
|
async downgradeStaleInferred(entityId, staleThreshold, tx) {
|
|
782
805
|
const executor = this.getExecutor(tx);
|
|
@@ -788,8 +811,8 @@ var EntryRepository = class extends BaseRepository {
|
|
|
788
811
|
AND source_type != 'immutable_document' AND deleted_at IS NULL`,
|
|
789
812
|
[entityId, staleThreshold, staleThreshold]
|
|
790
813
|
);
|
|
791
|
-
if (eligibleRows.length === 0) return
|
|
792
|
-
|
|
814
|
+
if (eligibleRows.length === 0) return [];
|
|
815
|
+
await executor.runAsync(
|
|
793
816
|
`UPDATE ${this.prefix}entries
|
|
794
817
|
SET confidence = 'tentative', updated_at = ?
|
|
795
818
|
WHERE entity_id = ? AND confidence = 'inferred' AND (last_accessed_at <= ? OR (last_accessed_at IS NULL AND created_at <= ?)) AND source_type != 'immutable_document' AND deleted_at IS NULL`,
|
|
@@ -804,7 +827,7 @@ var EntryRepository = class extends BaseRepository {
|
|
|
804
827
|
payload: { id: row.id, entity_id: entityId, confidence: "tentative", updated_at: now }
|
|
805
828
|
}, tx);
|
|
806
829
|
}
|
|
807
|
-
return
|
|
830
|
+
return eligibleRows.map((r) => r.id);
|
|
808
831
|
}
|
|
809
832
|
/**
|
|
810
833
|
* Downgrade specific entries to 'tentative' by IDs.
|
|
@@ -1123,6 +1146,58 @@ var EntryRepository = class extends BaseRepository {
|
|
|
1123
1146
|
);
|
|
1124
1147
|
return rows.map((r) => ({ id: r.id, title: r.title, okf_type: r.okf_type ?? null }));
|
|
1125
1148
|
}
|
|
1149
|
+
/** Counts live mutable facts: eligible (past cooldown) vs deferred (in cooldown). */
|
|
1150
|
+
async countHealCandidatesByEntityId(entityId, recheckCutoff, tx) {
|
|
1151
|
+
const executor = this.getExecutor(tx);
|
|
1152
|
+
const row = await executor.getFirstAsync(
|
|
1153
|
+
`SELECT
|
|
1154
|
+
SUM(CASE WHEN heal_checked_at IS NULL OR heal_checked_at <= ? THEN 1 ELSE 0 END) AS eligible,
|
|
1155
|
+
SUM(CASE WHEN heal_checked_at IS NOT NULL AND heal_checked_at > ? THEN 1 ELSE 0 END) AS deferred
|
|
1156
|
+
FROM ${this.prefix}entries
|
|
1157
|
+
WHERE entity_id = ? AND deleted_at IS NULL AND source_type != 'immutable_document'`,
|
|
1158
|
+
[recheckCutoff, recheckCutoff, entityId]
|
|
1159
|
+
);
|
|
1160
|
+
return { eligible: Number(row?.eligible ?? 0), deferred: Number(row?.deferred ?? 0) };
|
|
1161
|
+
}
|
|
1162
|
+
/**
|
|
1163
|
+
* Stamps the heal recheck cooldown. NEVER touches updated_at — import merge
|
|
1164
|
+
* resolution is last-write-wins on updated_at and a bump here would make an
|
|
1165
|
+
* unchanged local fact beat a genuinely newer remote edit.
|
|
1166
|
+
*
|
|
1167
|
+
* Soft-deleted rows are skipped: a candidate heal deleted earlier in the same
|
|
1168
|
+
* transaction is no longer a candidate under any future pass, so its cooldown
|
|
1169
|
+
* value is irrelevant. This means the stamped count can be lower than the
|
|
1170
|
+
* offered-candidate count.
|
|
1171
|
+
*/
|
|
1172
|
+
async markHealChecked(ids, entityId, now, tx) {
|
|
1173
|
+
if (ids.length === 0) return;
|
|
1174
|
+
for (let i = 0; i < ids.length; i += this.chunkSize) {
|
|
1175
|
+
const chunk = ids.slice(i, i + this.chunkSize);
|
|
1176
|
+
const placeholders = chunk.map(() => "?").join(",");
|
|
1177
|
+
await tx.runAsync(
|
|
1178
|
+
`UPDATE ${this.prefix}entries SET heal_checked_at = ?
|
|
1179
|
+
WHERE id IN (${placeholders}) AND entity_id = ? AND deleted_at IS NULL`,
|
|
1180
|
+
[now, ...chunk, entityId]
|
|
1181
|
+
);
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* Lightweight full-breadth index (id, title) over all live librarian_inferred
|
|
1186
|
+
* facts. This is heal's fuzzy-dedupe corpus, deliberately kept independent of
|
|
1187
|
+
* the bounded candidate window: seeding dedupe from a batchSize-limited read
|
|
1188
|
+
* would let a synthesized fact duplicating a fact outside the window pass the
|
|
1189
|
+
* Jaccard check, and a convergence loop would multiply those duplicates across
|
|
1190
|
+
* passes. Mirrors findTitleIndexByEntityId — full breadth, two columns, cheap.
|
|
1191
|
+
*/
|
|
1192
|
+
async findInferredTitlesByEntityId(entityId, tx) {
|
|
1193
|
+
const executor = this.getExecutor(tx);
|
|
1194
|
+
const rows = await executor.getAllAsync(
|
|
1195
|
+
`SELECT id, title FROM ${this.prefix}entries
|
|
1196
|
+
WHERE entity_id = ? AND deleted_at IS NULL AND source_type = 'librarian_inferred'`,
|
|
1197
|
+
[entityId]
|
|
1198
|
+
);
|
|
1199
|
+
return rows.map((r) => ({ id: r.id, title: r.title }));
|
|
1200
|
+
}
|
|
1126
1201
|
};
|
|
1127
1202
|
|
|
1128
1203
|
// src/repositories/OutboxRepository.ts
|
|
@@ -2021,9 +2096,23 @@ var WikiMemory = class {
|
|
|
2021
2096
|
return this.maintenanceService.runLibrarian(entityId, options);
|
|
2022
2097
|
}
|
|
2023
2098
|
/**
|
|
2099
|
+
* Reviews stored facts with the LLM: removes orphans, downgrades stale
|
|
2100
|
+
* inferences, synthesizes corrections.
|
|
2101
|
+
*
|
|
2102
|
+
* Bounded per call: covers at most `batchSize` candidates (default 25), so
|
|
2103
|
+
* one call no longer sweeps the whole entity. Hosts own the cadence; loop
|
|
2104
|
+
* `while (result.remaining > 0)` for convergence.
|
|
2105
|
+
*
|
|
2106
|
+
* `remaining === 0` means "every mutable fact is inside the 7-day recheck
|
|
2107
|
+
* cooldown", not "there is no more work" — heal's candidate set is the live
|
|
2108
|
+
* mutable corpus, not a draining backlog, so it climbs back as the cooldown
|
|
2109
|
+
* lapses and as new facts are written. Do not write a loop expecting a drain.
|
|
2110
|
+
*
|
|
2024
2111
|
* @param options.promptOverride - Applies only to this manual call. Does NOT affect
|
|
2025
2112
|
* WriteService-triggered auto-runs. For persistent prompt customization across auto-runs,
|
|
2026
2113
|
* set `options.config.prompts.healSystemPrompt` at WikiMemory construction time.
|
|
2114
|
+
* @param options.batchSize - Candidates per run (default 25) for providers with
|
|
2115
|
+
* tighter context limits.
|
|
2027
2116
|
*/
|
|
2028
2117
|
async runHeal(entityId, options) {
|
|
2029
2118
|
return this.maintenanceService.runHeal(entityId, options);
|