@plur-ai/core 0.9.2 → 0.9.3
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.
|
@@ -101,7 +101,11 @@ function searchEngrams(engrams, query, limit = 20) {
|
|
|
101
101
|
if (queryTokens.length === 0) return [];
|
|
102
102
|
const idfWeights = computeIdf(engrams, queryTokens);
|
|
103
103
|
const avgDocLength = engrams.length > 0 ? engrams.reduce((sum, e) => sum + ftsTokenize(engramSearchText(e)).length, 0) / engrams.length : 0;
|
|
104
|
-
|
|
104
|
+
let scored = engrams.map((e) => ({ engram: e, score: ftsScore(e, queryTokens, idfWeights, avgDocLength) })).filter((r) => r.score > 0);
|
|
105
|
+
if (scored.length === 0) {
|
|
106
|
+
scored = engrams.map((e) => ({ engram: e, score: ftsScore(e, queryTokens, void 0, avgDocLength) })).filter((r) => r.score > 0);
|
|
107
|
+
}
|
|
108
|
+
return scored.sort((a, b) => b.score - a.score).slice(0, limit).map((r) => r.engram);
|
|
105
109
|
}
|
|
106
110
|
|
|
107
111
|
// src/embeddings.ts
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
ftsScore,
|
|
7
7
|
ftsTokenize,
|
|
8
8
|
searchEngrams
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-IGGMRXAB.js";
|
|
10
10
|
import {
|
|
11
11
|
EngramSchemaPassthrough,
|
|
12
12
|
appendHistory,
|
|
@@ -33,12 +33,12 @@ import {
|
|
|
33
33
|
sync,
|
|
34
34
|
withLock
|
|
35
35
|
} from "./chunk-PRK3B7WR.js";
|
|
36
|
-
import
|
|
37
|
-
__require
|
|
38
|
-
} from "./chunk-2ZDO52B4.js";
|
|
36
|
+
import "./chunk-2ZDO52B4.js";
|
|
39
37
|
|
|
40
38
|
// src/index.ts
|
|
41
39
|
import * as fs4 from "fs";
|
|
40
|
+
import * as os from "os";
|
|
41
|
+
import * as path3 from "path";
|
|
42
42
|
import yaml6 from "js-yaml";
|
|
43
43
|
|
|
44
44
|
// src/storage.ts
|
|
@@ -772,8 +772,8 @@ function generateEpisodeId() {
|
|
|
772
772
|
const rand = Math.random().toString(36).slice(2, 6);
|
|
773
773
|
return `EP-${ts}-${rand}`;
|
|
774
774
|
}
|
|
775
|
-
function captureEpisode(
|
|
776
|
-
const episodes = loadEpisodes(
|
|
775
|
+
function captureEpisode(path4, summary, context) {
|
|
776
|
+
const episodes = loadEpisodes(path4);
|
|
777
777
|
const episode = {
|
|
778
778
|
id: generateEpisodeId(),
|
|
779
779
|
summary,
|
|
@@ -784,11 +784,11 @@ function captureEpisode(path3, summary, context) {
|
|
|
784
784
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
785
785
|
};
|
|
786
786
|
episodes.push(episode);
|
|
787
|
-
atomicWrite(
|
|
787
|
+
atomicWrite(path4, yaml2.dump(episodes, { lineWidth: 120, noRefs: true }));
|
|
788
788
|
return episode;
|
|
789
789
|
}
|
|
790
|
-
function queryTimeline(
|
|
791
|
-
let episodes = loadEpisodes(
|
|
790
|
+
function queryTimeline(path4, query) {
|
|
791
|
+
let episodes = loadEpisodes(path4);
|
|
792
792
|
if (query?.since) episodes = episodes.filter((e) => new Date(e.timestamp) >= query.since);
|
|
793
793
|
if (query?.until) episodes = episodes.filter((e) => new Date(e.timestamp) <= query.until);
|
|
794
794
|
if (query?.agent) episodes = episodes.filter((e) => e.agent === query.agent);
|
|
@@ -799,10 +799,10 @@ function queryTimeline(path3, query) {
|
|
|
799
799
|
}
|
|
800
800
|
return episodes;
|
|
801
801
|
}
|
|
802
|
-
function loadEpisodes(
|
|
803
|
-
if (!existsSync4(
|
|
802
|
+
function loadEpisodes(path4) {
|
|
803
|
+
if (!existsSync4(path4)) return [];
|
|
804
804
|
try {
|
|
805
|
-
const raw = yaml2.load(readFileSync2(
|
|
805
|
+
const raw = yaml2.load(readFileSync2(path4, "utf8"));
|
|
806
806
|
return Array.isArray(raw) ? raw : [];
|
|
807
807
|
} catch {
|
|
808
808
|
return [];
|
|
@@ -1585,7 +1585,7 @@ async function computeSimilarityMatrix(templates) {
|
|
|
1585
1585
|
const n = templates.length;
|
|
1586
1586
|
const matrix = Array.from({ length: n }, () => Array(n).fill(0));
|
|
1587
1587
|
try {
|
|
1588
|
-
const { embed, cosineSimilarity } = await import("./embeddings-
|
|
1588
|
+
const { embed, cosineSimilarity } = await import("./embeddings-ZRT6IRPA.js");
|
|
1589
1589
|
const embeddings = [];
|
|
1590
1590
|
for (const t of templates) {
|
|
1591
1591
|
embeddings.push(await embed(t));
|
|
@@ -3014,17 +3014,17 @@ var Plur = class {
|
|
|
3014
3014
|
return all;
|
|
3015
3015
|
}
|
|
3016
3016
|
/** Load engrams from a path with mtime-based caching */
|
|
3017
|
-
_loadCached(
|
|
3017
|
+
_loadCached(path4) {
|
|
3018
3018
|
let mtime;
|
|
3019
3019
|
try {
|
|
3020
|
-
mtime = fs4.statSync(
|
|
3020
|
+
mtime = fs4.statSync(path4, { bigint: true }).mtimeNs;
|
|
3021
3021
|
} catch {
|
|
3022
3022
|
return [];
|
|
3023
3023
|
}
|
|
3024
|
-
const cached = this._engramCache.get(
|
|
3024
|
+
const cached = this._engramCache.get(path4);
|
|
3025
3025
|
if (cached && cached.mtime === mtime) return cached.engrams;
|
|
3026
|
-
const engrams = loadEngrams(
|
|
3027
|
-
this._engramCache.set(
|
|
3026
|
+
const engrams = loadEngrams(path4);
|
|
3027
|
+
this._engramCache.set(path4, { mtime, engrams });
|
|
3028
3028
|
return engrams;
|
|
3029
3029
|
}
|
|
3030
3030
|
/**
|
|
@@ -3038,9 +3038,9 @@ var Plur = class {
|
|
|
3038
3038
|
* invalidation on write removes the filesystem as a source of cache
|
|
3039
3039
|
* freshness and closes the race. See issue #25.
|
|
3040
3040
|
*/
|
|
3041
|
-
_writeEngrams(
|
|
3042
|
-
saveEngrams(
|
|
3043
|
-
this._engramCache.delete(
|
|
3041
|
+
_writeEngrams(path4, engrams) {
|
|
3042
|
+
saveEngrams(path4, engrams);
|
|
3043
|
+
this._engramCache.delete(path4);
|
|
3044
3044
|
}
|
|
3045
3045
|
/** Find which store owns an engram by ID. For namespaced IDs, strips prefix to find in store. */
|
|
3046
3046
|
_findEngramStore(id) {
|
|
@@ -3201,12 +3201,12 @@ var Plur = class {
|
|
|
3201
3201
|
}
|
|
3202
3202
|
/** Async learn with LLM-driven deduplication (Ideas 1+2+19). */
|
|
3203
3203
|
async learnAsync(statement, context) {
|
|
3204
|
-
const { learnAsync: learnAsyncImpl } = await import("./learn-async-
|
|
3204
|
+
const { learnAsync: learnAsyncImpl } = await import("./learn-async-R5KZ5EWF.js");
|
|
3205
3205
|
return learnAsyncImpl(this._learnAsyncDeps(), statement, context);
|
|
3206
3206
|
}
|
|
3207
3207
|
/** Batch learn with LLM dedup. */
|
|
3208
3208
|
async learnBatch(statements, llm) {
|
|
3209
|
-
const { learnBatch: learnBatchImpl } = await import("./learn-async-
|
|
3209
|
+
const { learnBatch: learnBatchImpl } = await import("./learn-async-R5KZ5EWF.js");
|
|
3210
3210
|
return learnBatchImpl(this._learnAsyncDeps(), statements, llm);
|
|
3211
3211
|
}
|
|
3212
3212
|
/**
|
|
@@ -3875,21 +3875,20 @@ Generate an improved version of the procedure that prevents this failure. Return
|
|
|
3875
3875
|
autoDiscoverStores(cwd) {
|
|
3876
3876
|
const startDir = cwd || process.cwd();
|
|
3877
3877
|
const discovered = [];
|
|
3878
|
-
const os = __require("os");
|
|
3879
3878
|
const tmpDir = os.tmpdir();
|
|
3880
3879
|
if (this.paths.root.startsWith(tmpDir) || this.paths.root.startsWith("/tmp/")) {
|
|
3881
3880
|
return discovered;
|
|
3882
3881
|
}
|
|
3883
3882
|
const knownPaths = new Set((this.config.stores ?? []).map((s) => s.path));
|
|
3884
|
-
const primaryDir =
|
|
3883
|
+
const primaryDir = path3.dirname(this.paths.engrams);
|
|
3885
3884
|
let dir = startDir;
|
|
3886
|
-
const { join: join5, dirname:
|
|
3885
|
+
const { join: join5, dirname: dirname3, basename: basename2 } = path3;
|
|
3887
3886
|
const visited = /* @__PURE__ */ new Set();
|
|
3888
3887
|
while (dir && !visited.has(dir)) {
|
|
3889
3888
|
visited.add(dir);
|
|
3890
3889
|
const candidate = join5(dir, ".plur", "engrams.yaml");
|
|
3891
3890
|
if (join5(dir, ".plur") === primaryDir) {
|
|
3892
|
-
dir =
|
|
3891
|
+
dir = dirname3(dir);
|
|
3893
3892
|
continue;
|
|
3894
3893
|
}
|
|
3895
3894
|
if (fs4.existsSync(candidate) && !knownPaths.has(candidate)) {
|
|
@@ -3908,7 +3907,7 @@ Generate an improved version of the procedure that prevents this failure. Return
|
|
|
3908
3907
|
logger.info(`Auto-discovered project store: ${candidate} (${scope})`);
|
|
3909
3908
|
}
|
|
3910
3909
|
if (fs4.existsSync(join5(dir, ".git"))) break;
|
|
3911
|
-
const parent =
|
|
3910
|
+
const parent = dirname3(dir);
|
|
3912
3911
|
if (parent === dir) break;
|
|
3913
3912
|
dir = parent;
|
|
3914
3913
|
}
|
|
@@ -135,6 +135,9 @@ async function learnAsync(deps, statement, context) {
|
|
|
135
135
|
} catch {
|
|
136
136
|
candidates = deps.recall(statement, { limit: 5 });
|
|
137
137
|
}
|
|
138
|
+
if (candidates.length === 0) {
|
|
139
|
+
candidates = deps.recall(statement, { limit: 5 });
|
|
140
|
+
}
|
|
138
141
|
candidates = candidates.filter((c) => c.status === "active");
|
|
139
142
|
if (candidates.length === 0) {
|
|
140
143
|
return { engram: deps.learn(statement, context), decision: "ADD" };
|