@equationalapplications/core-llm-wiki 4.4.0 → 4.5.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/README.md +65 -0
- package/dist/index.d.mts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.js +56 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +53 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -398,6 +398,71 @@ await wikiMemory.write('user-123', {
|
|
|
398
398
|
const memory = await wikiMemory.read('user-123', 'coding style preferences');
|
|
399
399
|
```
|
|
400
400
|
|
|
401
|
+
### Multi-entity weighted reads
|
|
402
|
+
|
|
403
|
+
`read()` accepts either one entity id or an array of entity ids. Facts are always merged globally before `maxResults` is applied. For single-entity reads, tasks are uncapped and events are capped at 10. For multi-entity reads, tasks are capped at `min(20 × entity count, 200)` and events at `min(10 × entity count, 100)` — per-entity representation in the returned bundle is not guaranteed.
|
|
404
|
+
|
|
405
|
+
```ts
|
|
406
|
+
const memory = await wikiMemory.read(['tier_wisdom', 'tier_fact', 'tier_working'], 'Which source should I trust?', {
|
|
407
|
+
maxResults: 8,
|
|
408
|
+
tierWeights: {
|
|
409
|
+
tier_wisdom: 2,
|
|
410
|
+
tier_fact: 1,
|
|
411
|
+
tier_working: 0.25,
|
|
412
|
+
},
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
console.log(memory.metadata);
|
|
416
|
+
console.log(memory.factScores);
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### Librarian prompt override contract
|
|
420
|
+
|
|
421
|
+
Core does not own a provider-specific synthesis API, but it exports prompt utilities for applications that synthesize answers from weighted retrieval results.
|
|
422
|
+
|
|
423
|
+
```ts
|
|
424
|
+
import {
|
|
425
|
+
DEFAULT_LIBRARIAN_SYNTHESIS_PROMPT,
|
|
426
|
+
formatContext,
|
|
427
|
+
hydrateLibrarianPrompt,
|
|
428
|
+
mapLibrarianOptionsToReadOptions,
|
|
429
|
+
validateLibrarianPromptTemplate,
|
|
430
|
+
} from '@equationalapplications/core-llm-wiki';
|
|
431
|
+
|
|
432
|
+
const options = {
|
|
433
|
+
entityWeights: { tier_wisdom: 2, tier_fact: 1, tier_working: 0.25 },
|
|
434
|
+
systemPrompt: `You are a strict fact checker.
|
|
435
|
+
Question:
|
|
436
|
+
{{query}}
|
|
437
|
+
|
|
438
|
+
Retrieved context:
|
|
439
|
+
{{context}}
|
|
440
|
+
|
|
441
|
+
{{tasks}}`,
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
const query = 'Which source should I trust for recent project decisions?';
|
|
445
|
+
|
|
446
|
+
const memory = await wikiMemory.read(['tier_wisdom', 'tier_fact', 'tier_working'], query, {
|
|
447
|
+
...mapLibrarianOptionsToReadOptions(options),
|
|
448
|
+
maxResults: 8,
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
const template = options.systemPrompt ?? DEFAULT_LIBRARIAN_SYNTHESIS_PROMPT;
|
|
452
|
+
const warnings = validateLibrarianPromptTemplate(template, {
|
|
453
|
+
custom: options.systemPrompt != null,
|
|
454
|
+
taskCount: memory.tasks.length,
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
for (const warning of warnings) console.warn(warning);
|
|
458
|
+
|
|
459
|
+
const finalPrompt = hydrateLibrarianPrompt(template, {
|
|
460
|
+
query,
|
|
461
|
+
context: formatContext(memory, { includeEntityIds: true, includeFactScores: true }),
|
|
462
|
+
tasks: formatContext({ facts: [], tasks: memory.tasks, events: [] }, { format: 'plain' }),
|
|
463
|
+
});
|
|
464
|
+
```
|
|
465
|
+
|
|
401
466
|
## Adapter Interface
|
|
402
467
|
|
|
403
468
|
Implement `SQLiteAdapter` to use your platform's SQLite driver:
|
package/dist/index.d.mts
CHANGED
|
@@ -313,6 +313,8 @@ interface FormatContextOptions {
|
|
|
313
313
|
maxEvents?: number;
|
|
314
314
|
includeConfidence?: boolean;
|
|
315
315
|
includeTags?: boolean;
|
|
316
|
+
includeEntityIds?: boolean;
|
|
317
|
+
includeFactScores?: boolean;
|
|
316
318
|
factWeights?: {
|
|
317
319
|
confidence?: number;
|
|
318
320
|
accessCount?: number;
|
|
@@ -531,6 +533,28 @@ declare function formatMemoryDump(dump: MemoryDump): FormattedMemoryDump;
|
|
|
531
533
|
|
|
532
534
|
declare function parseEmbedding(blob: Uint8Array | null | undefined, text: string | null | undefined): Float32Array | null;
|
|
533
535
|
|
|
536
|
+
interface LibrarianOptions {
|
|
537
|
+
/** If provided, replaces the default Librarian system instructions. */
|
|
538
|
+
systemPrompt?: string;
|
|
539
|
+
/** entity_id -> score multiplier, forwarded to WikiMemory.read() as tierWeights. */
|
|
540
|
+
entityWeights?: Record<string, number>;
|
|
541
|
+
/** Forwarded to WikiMemory.read() for zero-weight filler context. */
|
|
542
|
+
includeZeroWeightEntities?: boolean;
|
|
543
|
+
temperature?: number;
|
|
544
|
+
}
|
|
545
|
+
interface LibrarianPromptVariables {
|
|
546
|
+
context: string;
|
|
547
|
+
tasks: string;
|
|
548
|
+
query: string;
|
|
549
|
+
}
|
|
550
|
+
declare const DEFAULT_LIBRARIAN_SYNTHESIS_PROMPT = "You are a careful memory synthesis assistant.\nUse only the retrieved context when answering the request.\nPreserve source provenance when facts come from different entity namespaces.\n\nRequest:\n{{query}}\n\nRetrieved context:\n{{context}}\n\nOpen tasks:\n{{tasks}}";
|
|
551
|
+
declare function hydrateLibrarianPrompt(template: string, variables: LibrarianPromptVariables): string;
|
|
552
|
+
declare function validateLibrarianPromptTemplate(template: string, options: {
|
|
553
|
+
custom: boolean;
|
|
554
|
+
taskCount: number;
|
|
555
|
+
}): string[];
|
|
556
|
+
declare function mapLibrarianOptionsToReadOptions(options: LibrarianOptions): Pick<ReadOptions, 'tierWeights' | 'includeZeroWeightEntities'>;
|
|
557
|
+
|
|
534
558
|
declare function createWiki(db: SQLiteAdapter, options: WikiOptions): WikiMemory;
|
|
535
559
|
|
|
536
|
-
export { type EntityStatus, type ExtractedFact, type ExtractedTask, type FormatContextOptions, type FormattedMemoryDump, type LLMProvider, type MemoryBundle, type MemoryDump, PrunePartialFailureError, type ReadOptions, type SQLiteAdapter, type VectorRanker, type VectorRankerFallback, type VectorRankerRankArgs, type VectorRankerSemanticResult, WikiBusyError, type WikiBusyOperation, type WikiCheckpoint, type WikiConfig, type WikiEvent, type WikiFact, WikiMemory, type WikiOptions, type WikiTask, createWiki, formatContext, formatMemoryDump, parseEmbedding };
|
|
560
|
+
export { DEFAULT_LIBRARIAN_SYNTHESIS_PROMPT, type EntityStatus, type ExtractedFact, type ExtractedTask, type FormatContextOptions, type FormattedMemoryDump, type LLMProvider, type LibrarianOptions, type LibrarianPromptVariables, type MemoryBundle, type MemoryDump, PrunePartialFailureError, type ReadOptions, type SQLiteAdapter, type VectorRanker, type VectorRankerFallback, type VectorRankerRankArgs, type VectorRankerSemanticResult, WikiBusyError, type WikiBusyOperation, type WikiCheckpoint, type WikiConfig, type WikiEvent, type WikiFact, WikiMemory, type WikiOptions, type WikiTask, createWiki, formatContext, formatMemoryDump, hydrateLibrarianPrompt, mapLibrarianOptionsToReadOptions, parseEmbedding, validateLibrarianPromptTemplate };
|
package/dist/index.d.ts
CHANGED
|
@@ -313,6 +313,8 @@ interface FormatContextOptions {
|
|
|
313
313
|
maxEvents?: number;
|
|
314
314
|
includeConfidence?: boolean;
|
|
315
315
|
includeTags?: boolean;
|
|
316
|
+
includeEntityIds?: boolean;
|
|
317
|
+
includeFactScores?: boolean;
|
|
316
318
|
factWeights?: {
|
|
317
319
|
confidence?: number;
|
|
318
320
|
accessCount?: number;
|
|
@@ -531,6 +533,28 @@ declare function formatMemoryDump(dump: MemoryDump): FormattedMemoryDump;
|
|
|
531
533
|
|
|
532
534
|
declare function parseEmbedding(blob: Uint8Array | null | undefined, text: string | null | undefined): Float32Array | null;
|
|
533
535
|
|
|
536
|
+
interface LibrarianOptions {
|
|
537
|
+
/** If provided, replaces the default Librarian system instructions. */
|
|
538
|
+
systemPrompt?: string;
|
|
539
|
+
/** entity_id -> score multiplier, forwarded to WikiMemory.read() as tierWeights. */
|
|
540
|
+
entityWeights?: Record<string, number>;
|
|
541
|
+
/** Forwarded to WikiMemory.read() for zero-weight filler context. */
|
|
542
|
+
includeZeroWeightEntities?: boolean;
|
|
543
|
+
temperature?: number;
|
|
544
|
+
}
|
|
545
|
+
interface LibrarianPromptVariables {
|
|
546
|
+
context: string;
|
|
547
|
+
tasks: string;
|
|
548
|
+
query: string;
|
|
549
|
+
}
|
|
550
|
+
declare const DEFAULT_LIBRARIAN_SYNTHESIS_PROMPT = "You are a careful memory synthesis assistant.\nUse only the retrieved context when answering the request.\nPreserve source provenance when facts come from different entity namespaces.\n\nRequest:\n{{query}}\n\nRetrieved context:\n{{context}}\n\nOpen tasks:\n{{tasks}}";
|
|
551
|
+
declare function hydrateLibrarianPrompt(template: string, variables: LibrarianPromptVariables): string;
|
|
552
|
+
declare function validateLibrarianPromptTemplate(template: string, options: {
|
|
553
|
+
custom: boolean;
|
|
554
|
+
taskCount: number;
|
|
555
|
+
}): string[];
|
|
556
|
+
declare function mapLibrarianOptionsToReadOptions(options: LibrarianOptions): Pick<ReadOptions, 'tierWeights' | 'includeZeroWeightEntities'>;
|
|
557
|
+
|
|
534
558
|
declare function createWiki(db: SQLiteAdapter, options: WikiOptions): WikiMemory;
|
|
535
559
|
|
|
536
|
-
export { type EntityStatus, type ExtractedFact, type ExtractedTask, type FormatContextOptions, type FormattedMemoryDump, type LLMProvider, type MemoryBundle, type MemoryDump, PrunePartialFailureError, type ReadOptions, type SQLiteAdapter, type VectorRanker, type VectorRankerFallback, type VectorRankerRankArgs, type VectorRankerSemanticResult, WikiBusyError, type WikiBusyOperation, type WikiCheckpoint, type WikiConfig, type WikiEvent, type WikiFact, WikiMemory, type WikiOptions, type WikiTask, createWiki, formatContext, formatMemoryDump, parseEmbedding };
|
|
560
|
+
export { DEFAULT_LIBRARIAN_SYNTHESIS_PROMPT, type EntityStatus, type ExtractedFact, type ExtractedTask, type FormatContextOptions, type FormattedMemoryDump, type LLMProvider, type LibrarianOptions, type LibrarianPromptVariables, type MemoryBundle, type MemoryDump, PrunePartialFailureError, type ReadOptions, type SQLiteAdapter, type VectorRanker, type VectorRankerFallback, type VectorRankerRankArgs, type VectorRankerSemanticResult, WikiBusyError, type WikiBusyOperation, type WikiCheckpoint, type WikiConfig, type WikiEvent, type WikiFact, WikiMemory, type WikiOptions, type WikiTask, createWiki, formatContext, formatMemoryDump, hydrateLibrarianPrompt, mapLibrarianOptionsToReadOptions, parseEmbedding, validateLibrarianPromptTemplate };
|
package/dist/index.js
CHANGED
|
@@ -2793,16 +2793,20 @@ function scoreFactFor(fact, weights, now) {
|
|
|
2793
2793
|
const recencyDecay = Math.exp(-ageDays / 30);
|
|
2794
2794
|
return confW * weights.confidence + Math.log(1 + fact.access_count) * weights.accessCount + recencyDecay * weights.recency;
|
|
2795
2795
|
}
|
|
2796
|
-
function renderFactMarkdown(fact, includeConfidence, includeTags) {
|
|
2796
|
+
function renderFactMarkdown(fact, includeConfidence, includeTags, includeEntityIds, score) {
|
|
2797
2797
|
const confPart = includeConfidence ? ` (${fact.confidence})` : "";
|
|
2798
2798
|
const tagPart = includeTags && fact.tags.length > 0 ? ` [${fact.tags.join(", ")}]` : "";
|
|
2799
|
-
|
|
2799
|
+
const sourcePart = includeEntityIds ? ` {entity_id=${fact.entity_id}}` : "";
|
|
2800
|
+
const scorePart = score !== void 0 ? ` {score=${score.toFixed(4)}}` : "";
|
|
2801
|
+
return `- **${fact.title}**${confPart}${tagPart}${sourcePart}${scorePart}
|
|
2800
2802
|
${fact.body.replace(/\n/g, "\n ")}`;
|
|
2801
2803
|
}
|
|
2802
|
-
function renderFactPlain(fact, includeConfidence, includeTags) {
|
|
2804
|
+
function renderFactPlain(fact, includeConfidence, includeTags, includeEntityIds, score) {
|
|
2803
2805
|
const confPart = includeConfidence ? ` (${fact.confidence})` : "";
|
|
2804
2806
|
const tagPart = includeTags && fact.tags.length > 0 ? ` [${fact.tags.join(", ")}]` : "";
|
|
2805
|
-
|
|
2807
|
+
const sourcePart = includeEntityIds ? ` {entity_id=${fact.entity_id}}` : "";
|
|
2808
|
+
const scorePart = score !== void 0 ? ` {score=${score.toFixed(4)}}` : "";
|
|
2809
|
+
return `${fact.title}${confPart}${tagPart}${sourcePart}${scorePart}: ${fact.body}`;
|
|
2806
2810
|
}
|
|
2807
2811
|
function renderTaskMarkdown(task) {
|
|
2808
2812
|
return `- [P${task.priority}] ${task.description.replace(/\n/g, "\n ")} (${task.status})`;
|
|
@@ -2826,6 +2830,8 @@ function formatContext(bundle, options) {
|
|
|
2826
2830
|
maxEvents: options?.maxEvents ?? 10,
|
|
2827
2831
|
includeConfidence: options?.includeConfidence ?? true,
|
|
2828
2832
|
includeTags: options?.includeTags ?? true,
|
|
2833
|
+
includeEntityIds: options?.includeEntityIds ?? false,
|
|
2834
|
+
includeFactScores: options?.includeFactScores ?? false,
|
|
2829
2835
|
factWeights: {
|
|
2830
2836
|
confidence: options?.factWeights?.confidence ?? 1,
|
|
2831
2837
|
accessCount: options?.factWeights?.accessCount ?? 0.3,
|
|
@@ -2837,7 +2843,7 @@ function formatContext(bundle, options) {
|
|
|
2837
2843
|
validateMaxOption(opts.maxEvents, "maxEvents");
|
|
2838
2844
|
const weights = opts.factWeights;
|
|
2839
2845
|
const now = Date.now();
|
|
2840
|
-
const sortedFacts = [...bundle.facts].sort((a, b) => scoreFactFor(b, weights, now) - scoreFactFor(a, weights, now)).slice(0, opts.maxFacts);
|
|
2846
|
+
const sortedFacts = bundle.factScores ? [...bundle.facts].slice(0, opts.maxFacts) : [...bundle.facts].sort((a, b) => scoreFactFor(b, weights, now) - scoreFactFor(a, weights, now)).slice(0, opts.maxFacts);
|
|
2841
2847
|
const sortedTasks = [...bundle.tasks].sort((a, b) => b.priority - a.priority || a.created_at - b.created_at).slice(0, opts.maxTasks);
|
|
2842
2848
|
const sortedEvents = [...bundle.events].sort((a, b) => b.created_at - a.created_at).slice(0, opts.maxEvents);
|
|
2843
2849
|
if (sortedFacts.length === 0 && sortedTasks.length === 0 && sortedEvents.length === 0) {
|
|
@@ -2851,7 +2857,7 @@ function formatContext(bundle, options) {
|
|
|
2851
2857
|
lines.push("");
|
|
2852
2858
|
lines.push("### Known Facts");
|
|
2853
2859
|
for (const fact of sortedFacts) {
|
|
2854
|
-
lines.push(renderFactMarkdown(fact, opts.includeConfidence, opts.includeTags));
|
|
2860
|
+
lines.push(renderFactMarkdown(fact, opts.includeConfidence, opts.includeTags, opts.includeEntityIds, opts.includeFactScores ? bundle.factScores?.[fact.id] : void 0));
|
|
2855
2861
|
}
|
|
2856
2862
|
}
|
|
2857
2863
|
if (sortedTasks.length > 0) {
|
|
@@ -2872,7 +2878,7 @@ function formatContext(bundle, options) {
|
|
|
2872
2878
|
if (sortedFacts.length > 0) {
|
|
2873
2879
|
lines.push("KNOWN FACTS:");
|
|
2874
2880
|
for (const fact of sortedFacts) {
|
|
2875
|
-
lines.push(renderFactPlain(fact, opts.includeConfidence, opts.includeTags));
|
|
2881
|
+
lines.push(renderFactPlain(fact, opts.includeConfidence, opts.includeTags, opts.includeEntityIds, opts.includeFactScores ? bundle.factScores?.[fact.id] : void 0));
|
|
2876
2882
|
}
|
|
2877
2883
|
}
|
|
2878
2884
|
if (sortedTasks.length > 0) {
|
|
@@ -2991,17 +2997,60 @@ function formatMemoryDump(dump) {
|
|
|
2991
2997
|
};
|
|
2992
2998
|
}
|
|
2993
2999
|
|
|
3000
|
+
// src/librarianPrompt.ts
|
|
3001
|
+
var DEFAULT_LIBRARIAN_SYNTHESIS_PROMPT = `You are a careful memory synthesis assistant.
|
|
3002
|
+
Use only the retrieved context when answering the request.
|
|
3003
|
+
Preserve source provenance when facts come from different entity namespaces.
|
|
3004
|
+
|
|
3005
|
+
Request:
|
|
3006
|
+
{{query}}
|
|
3007
|
+
|
|
3008
|
+
Retrieved context:
|
|
3009
|
+
{{context}}
|
|
3010
|
+
|
|
3011
|
+
Open tasks:
|
|
3012
|
+
{{tasks}}`;
|
|
3013
|
+
function hydrateLibrarianPrompt(template, variables) {
|
|
3014
|
+
return template.replace(/\{\{(context|tasks|query)\}\}/g, (_, key) => variables[key]);
|
|
3015
|
+
}
|
|
3016
|
+
function validateLibrarianPromptTemplate(template, options) {
|
|
3017
|
+
if (!options.custom) return [];
|
|
3018
|
+
const warnings = [];
|
|
3019
|
+
if (!template.includes("{{context}}")) {
|
|
3020
|
+
warnings.push("Custom Librarian systemPrompt omits {{context}}; retrieved memory will not be injected.");
|
|
3021
|
+
}
|
|
3022
|
+
if (!template.includes("{{query}}")) {
|
|
3023
|
+
warnings.push("Custom Librarian systemPrompt omits {{query}}; the original request will not be injected.");
|
|
3024
|
+
}
|
|
3025
|
+
if (options.taskCount > 0 && !template.includes("{{tasks}}")) {
|
|
3026
|
+
warnings.push("Custom Librarian systemPrompt omits {{tasks}} while retrieved tasks are available.");
|
|
3027
|
+
}
|
|
3028
|
+
return warnings;
|
|
3029
|
+
}
|
|
3030
|
+
function mapLibrarianOptionsToReadOptions(options) {
|
|
3031
|
+
const readOptions = {};
|
|
3032
|
+
if (options.entityWeights !== void 0) readOptions.tierWeights = options.entityWeights;
|
|
3033
|
+
if (options.includeZeroWeightEntities !== void 0) {
|
|
3034
|
+
readOptions.includeZeroWeightEntities = options.includeZeroWeightEntities;
|
|
3035
|
+
}
|
|
3036
|
+
return readOptions;
|
|
3037
|
+
}
|
|
3038
|
+
|
|
2994
3039
|
// src/index.ts
|
|
2995
3040
|
function createWiki(db, options) {
|
|
2996
3041
|
return new WikiMemory(db, options);
|
|
2997
3042
|
}
|
|
2998
3043
|
|
|
3044
|
+
exports.DEFAULT_LIBRARIAN_SYNTHESIS_PROMPT = DEFAULT_LIBRARIAN_SYNTHESIS_PROMPT;
|
|
2999
3045
|
exports.PrunePartialFailureError = PrunePartialFailureError;
|
|
3000
3046
|
exports.WikiBusyError = WikiBusyError;
|
|
3001
3047
|
exports.WikiMemory = WikiMemory;
|
|
3002
3048
|
exports.createWiki = createWiki;
|
|
3003
3049
|
exports.formatContext = formatContext;
|
|
3004
3050
|
exports.formatMemoryDump = formatMemoryDump;
|
|
3051
|
+
exports.hydrateLibrarianPrompt = hydrateLibrarianPrompt;
|
|
3052
|
+
exports.mapLibrarianOptionsToReadOptions = mapLibrarianOptionsToReadOptions;
|
|
3005
3053
|
exports.parseEmbedding = parseEmbedding;
|
|
3054
|
+
exports.validateLibrarianPromptTemplate = validateLibrarianPromptTemplate;
|
|
3006
3055
|
//# sourceMappingURL=index.js.map
|
|
3007
3056
|
//# sourceMappingURL=index.js.map
|