@plur-ai/core 0.9.1 → 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
- return engrams.map((e) => ({ engram: e, score: ftsScore(e, queryTokens, idfWeights, avgDocLength) })).filter((r) => r.score > 0).sort((a, b) => b.score - a.score).slice(0, limit).map((r) => r.engram);
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
@@ -3,7 +3,7 @@ import {
3
3
  embed,
4
4
  embeddingSearch,
5
5
  embeddingSearchWithScores
6
- } from "./chunk-MW5EPL7G.js";
6
+ } from "./chunk-IGGMRXAB.js";
7
7
  import "./chunk-PRK3B7WR.js";
8
8
  import "./chunk-2ZDO52B4.js";
9
9
  export {
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  ftsScore,
7
7
  ftsTokenize,
8
8
  searchEngrams
9
- } from "./chunk-MW5EPL7G.js";
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(path3, summary, context) {
776
- const episodes = loadEpisodes(path3);
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(path3, yaml2.dump(episodes, { lineWidth: 120, noRefs: true }));
787
+ atomicWrite(path4, yaml2.dump(episodes, { lineWidth: 120, noRefs: true }));
788
788
  return episode;
789
789
  }
790
- function queryTimeline(path3, query) {
791
- let episodes = loadEpisodes(path3);
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(path3) {
803
- if (!existsSync4(path3)) return [];
802
+ function loadEpisodes(path4) {
803
+ if (!existsSync4(path4)) return [];
804
804
  try {
805
- const raw = yaml2.load(readFileSync2(path3, "utf8"));
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-VXK2E2IF.js");
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));
@@ -2966,6 +2966,10 @@ var Plur = class {
2966
2966
  constructor(options) {
2967
2967
  this.paths = detectPlurStorage(options?.path);
2968
2968
  this.config = loadConfig(this.paths.config);
2969
+ this.autoDiscoverStores();
2970
+ if (this.config.stores?.length !== loadConfig(this.paths.config).stores?.length) {
2971
+ this.config = loadConfig(this.paths.config);
2972
+ }
2969
2973
  if (this.config.index) {
2970
2974
  this.indexedStorage = new IndexedStorage(this.paths.engrams, this.paths.db, this.config.stores);
2971
2975
  }
@@ -3010,17 +3014,17 @@ var Plur = class {
3010
3014
  return all;
3011
3015
  }
3012
3016
  /** Load engrams from a path with mtime-based caching */
3013
- _loadCached(path3) {
3017
+ _loadCached(path4) {
3014
3018
  let mtime;
3015
3019
  try {
3016
- mtime = fs4.statSync(path3, { bigint: true }).mtimeNs;
3020
+ mtime = fs4.statSync(path4, { bigint: true }).mtimeNs;
3017
3021
  } catch {
3018
3022
  return [];
3019
3023
  }
3020
- const cached = this._engramCache.get(path3);
3024
+ const cached = this._engramCache.get(path4);
3021
3025
  if (cached && cached.mtime === mtime) return cached.engrams;
3022
- const engrams = loadEngrams(path3);
3023
- this._engramCache.set(path3, { mtime, engrams });
3026
+ const engrams = loadEngrams(path4);
3027
+ this._engramCache.set(path4, { mtime, engrams });
3024
3028
  return engrams;
3025
3029
  }
3026
3030
  /**
@@ -3034,9 +3038,9 @@ var Plur = class {
3034
3038
  * invalidation on write removes the filesystem as a source of cache
3035
3039
  * freshness and closes the race. See issue #25.
3036
3040
  */
3037
- _writeEngrams(path3, engrams) {
3038
- saveEngrams(path3, engrams);
3039
- this._engramCache.delete(path3);
3041
+ _writeEngrams(path4, engrams) {
3042
+ saveEngrams(path4, engrams);
3043
+ this._engramCache.delete(path4);
3040
3044
  }
3041
3045
  /** Find which store owns an engram by ID. For namespaced IDs, strips prefix to find in store. */
3042
3046
  _findEngramStore(id) {
@@ -3197,12 +3201,12 @@ var Plur = class {
3197
3201
  }
3198
3202
  /** Async learn with LLM-driven deduplication (Ideas 1+2+19). */
3199
3203
  async learnAsync(statement, context) {
3200
- const { learnAsync: learnAsyncImpl } = await import("./learn-async-UZAPPQK4.js");
3204
+ const { learnAsync: learnAsyncImpl } = await import("./learn-async-R5KZ5EWF.js");
3201
3205
  return learnAsyncImpl(this._learnAsyncDeps(), statement, context);
3202
3206
  }
3203
3207
  /** Batch learn with LLM dedup. */
3204
3208
  async learnBatch(statements, llm) {
3205
- const { learnBatch: learnBatchImpl } = await import("./learn-async-UZAPPQK4.js");
3209
+ const { learnBatch: learnBatchImpl } = await import("./learn-async-R5KZ5EWF.js");
3206
3210
  return learnBatchImpl(this._learnAsyncDeps(), statements, llm);
3207
3211
  }
3208
3212
  /**
@@ -3871,21 +3875,20 @@ Generate an improved version of the procedure that prevents this failure. Return
3871
3875
  autoDiscoverStores(cwd) {
3872
3876
  const startDir = cwd || process.cwd();
3873
3877
  const discovered = [];
3874
- const os = __require("os");
3875
3878
  const tmpDir = os.tmpdir();
3876
3879
  if (this.paths.root.startsWith(tmpDir) || this.paths.root.startsWith("/tmp/")) {
3877
3880
  return discovered;
3878
3881
  }
3879
3882
  const knownPaths = new Set((this.config.stores ?? []).map((s) => s.path));
3880
- const primaryDir = __require("path").dirname(this.paths.engrams);
3883
+ const primaryDir = path3.dirname(this.paths.engrams);
3881
3884
  let dir = startDir;
3882
- const { join: join5, dirname: dirname2, basename: basename2 } = __require("path");
3885
+ const { join: join5, dirname: dirname3, basename: basename2 } = path3;
3883
3886
  const visited = /* @__PURE__ */ new Set();
3884
3887
  while (dir && !visited.has(dir)) {
3885
3888
  visited.add(dir);
3886
3889
  const candidate = join5(dir, ".plur", "engrams.yaml");
3887
3890
  if (join5(dir, ".plur") === primaryDir) {
3888
- dir = dirname2(dir);
3891
+ dir = dirname3(dir);
3889
3892
  continue;
3890
3893
  }
3891
3894
  if (fs4.existsSync(candidate) && !knownPaths.has(candidate)) {
@@ -3904,7 +3907,7 @@ Generate an improved version of the procedure that prevents this failure. Return
3904
3907
  logger.info(`Auto-discovered project store: ${candidate} (${scope})`);
3905
3908
  }
3906
3909
  if (fs4.existsSync(join5(dir, ".git"))) break;
3907
- const parent = dirname2(dir);
3910
+ const parent = dirname3(dir);
3908
3911
  if (parent === dir) break;
3909
3912
  dir = parent;
3910
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" };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plur-ai/core",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",