@jcyamacho/agent-memory 0.0.5 → 0.0.6

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.
Files changed (3) hide show
  1. package/README.md +1 -3
  2. package/dist/index.js +43 -26
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -102,8 +102,6 @@ Inputs:
102
102
  Output:
103
103
 
104
104
  - `id`
105
- - `workspace`
106
- - `created_at`
107
105
 
108
106
  ### `recall`
109
107
 
@@ -120,7 +118,7 @@ Inputs:
120
118
 
121
119
  Output:
122
120
 
123
- - `results[]` with `id`, `content`, `score`, `workspace`, and `created_at`
121
+ - `results[]` with `id`, `content`, `score`, `workspace`, and `updated_at`
124
122
 
125
123
  ## Setup
126
124
 
package/dist/index.js CHANGED
@@ -12464,7 +12464,7 @@ class StdioServerTransport {
12464
12464
  }
12465
12465
  }
12466
12466
  // package.json
12467
- var version2 = "0.0.5";
12467
+ var version2 = "0.0.6";
12468
12468
 
12469
12469
  // src/config.ts
12470
12470
  import { homedir } from "node:os";
@@ -19908,9 +19908,17 @@ class PersistenceError extends MemoryError {
19908
19908
  }
19909
19909
  }
19910
19910
 
19911
+ // src/memory.ts
19912
+ var toNormalizedScore = (value) => value;
19913
+
19911
19914
  // src/memory-service.ts
19912
19915
  var DEFAULT_LIMIT = 15;
19913
19916
  var MAX_LIMIT = 50;
19917
+ var RECALL_CANDIDATE_LIMIT_MULTIPLIER = 2;
19918
+ var RETRIEVAL_SCORE_WEIGHT = 8;
19919
+ var WORKSPACE_MATCH_WEIGHT = 2;
19920
+ var RECENCY_WEIGHT = 1;
19921
+ var MAX_COMPOSITE_SCORE = RETRIEVAL_SCORE_WEIGHT + WORKSPACE_MATCH_WEIGHT + RECENCY_WEIGHT;
19914
19922
 
19915
19923
  class MemoryService {
19916
19924
  repository;
@@ -19937,14 +19945,17 @@ class MemoryService {
19937
19945
  if (terms.length === 0) {
19938
19946
  throw new ValidationError("At least one search term is required.");
19939
19947
  }
19948
+ const requestedLimit = normalizeLimit(input.limit);
19949
+ const workspace = normalizeOptionalString(input.workspace);
19940
19950
  const normalizedQuery = {
19941
19951
  terms,
19942
- limit: normalizeLimit(input.limit),
19943
- workspace: normalizeOptionalString(input.workspace),
19952
+ limit: requestedLimit * RECALL_CANDIDATE_LIMIT_MULTIPLIER,
19944
19953
  createdAfter: input.createdAfter,
19945
19954
  createdBefore: input.createdBefore
19946
19955
  };
19947
- return this.repository.search(normalizedQuery);
19956
+ const results = await this.repository.search(normalizedQuery);
19957
+ const reranked = rerankSearchResults(results, workspace);
19958
+ return reranked.sort((a, b) => b.score - a.score).slice(0, requestedLimit);
19948
19959
  }
19949
19960
  }
19950
19961
  var normalizeLimit = (value) => {
@@ -19964,6 +19975,23 @@ var normalizeTerms = (terms) => {
19964
19975
  const normalizedTerms = terms.map((term) => term.trim()).filter(Boolean);
19965
19976
  return [...new Set(normalizedTerms)];
19966
19977
  };
19978
+ var rerankSearchResults = (results, workspace) => {
19979
+ if (results.length <= 1) {
19980
+ return results;
19981
+ }
19982
+ const updatedAtTimes = results.map((result) => result.updatedAt.getTime());
19983
+ const minUpdatedAt = Math.min(...updatedAtTimes);
19984
+ const maxUpdatedAt = Math.max(...updatedAtTimes);
19985
+ return [...results].map((result) => {
19986
+ const workspaceScore = workspace && result.workspace === workspace ? 1 : 0;
19987
+ const recencyScore = maxUpdatedAt === minUpdatedAt ? 0 : (result.updatedAt.getTime() - minUpdatedAt) / (maxUpdatedAt - minUpdatedAt);
19988
+ const combinedScore = (result.score * RETRIEVAL_SCORE_WEIGHT + workspaceScore * WORKSPACE_MATCH_WEIGHT + recencyScore * RECENCY_WEIGHT) / MAX_COMPOSITE_SCORE;
19989
+ return {
19990
+ ...result,
19991
+ score: toNormalizedScore(combinedScore)
19992
+ };
19993
+ });
19994
+ };
19967
19995
 
19968
19996
  // src/tools/shared.ts
19969
19997
  var toMcpError = (error2) => {
@@ -20004,7 +20032,7 @@ var recallOutputSchema = {
20004
20032
  content: string2().describe("Saved memory text that matched one or more search terms."),
20005
20033
  score: number2().describe("Relative relevance score for ranking results. Higher means a stronger match."),
20006
20034
  workspace: string2().optional().describe("Workspace associated with the memory, if available."),
20007
- created_at: string2().describe("ISO 8601 timestamp showing when the memory was created.")
20035
+ updated_at: string2().describe("ISO 8601 timestamp showing when the memory was last updated.")
20008
20036
  }))
20009
20037
  };
20010
20038
  var registerRecallTool = (server, memoryService) => {
@@ -20027,7 +20055,7 @@ var registerRecallTool = (server, memoryService) => {
20027
20055
  content: result.content,
20028
20056
  score: result.score,
20029
20057
  workspace: result.workspace,
20030
- created_at: result.createdAt.toISOString()
20058
+ updated_at: result.updatedAt.toISOString()
20031
20059
  }))
20032
20060
  };
20033
20061
  const matchCount = structuredContent.results.length;
@@ -20053,9 +20081,7 @@ var rememberInputSchema = {
20053
20081
  workspace: string2().optional().describe("Repository or workspace path this memory belongs to. Use it to keep memories scoped to a project.")
20054
20082
  };
20055
20083
  var rememberOutputSchema = {
20056
- id: string2().describe("Stable identifier for the saved memory."),
20057
- workspace: string2().optional().describe("Workspace stored with the memory, if provided."),
20058
- created_at: string2().describe("ISO 8601 timestamp showing when the memory was created.")
20084
+ id: string2().describe("Stable identifier for the saved memory.")
20059
20085
  };
20060
20086
  var registerRememberTool = (server, memoryService) => {
20061
20087
  server.registerTool("remember", {
@@ -20069,9 +20095,7 @@ var registerRememberTool = (server, memoryService) => {
20069
20095
  workspace
20070
20096
  });
20071
20097
  const structuredContent = {
20072
- id: memory.id,
20073
- workspace: memory.workspace,
20074
- created_at: memory.createdAt.toISOString()
20098
+ id: memory.id
20075
20099
  };
20076
20100
  return {
20077
20101
  content: [
@@ -20165,8 +20189,6 @@ var initializeMemoryDatabase = (database) => {
20165
20189
  };
20166
20190
 
20167
20191
  // src/sqlite-repository.ts
20168
- var WORKSPACE_BIAS = 0.1;
20169
-
20170
20192
  class SqliteMemoryRepository {
20171
20193
  database;
20172
20194
  insertStatement;
@@ -20198,15 +20220,7 @@ class SqliteMemoryRepository {
20198
20220
  }
20199
20221
  async search(query) {
20200
20222
  try {
20201
- const selectParams = [];
20202
20223
  const whereParams = [toFtsQuery(query.terms)];
20203
- let scoreExpr;
20204
- if (query.workspace) {
20205
- scoreExpr = "MAX(0, -bm25(memories_fts) + CASE WHEN m.workspace = ? THEN ? ELSE 0.0 END)";
20206
- selectParams.push(query.workspace, WORKSPACE_BIAS);
20207
- } else {
20208
- scoreExpr = "MAX(0, -bm25(memories_fts))";
20209
- }
20210
20224
  const whereClauses = ["memories_fts MATCH ?"];
20211
20225
  if (query.createdAfter) {
20212
20226
  whereClauses.push("m.created_at >= ?");
@@ -20216,14 +20230,15 @@ class SqliteMemoryRepository {
20216
20230
  whereClauses.push("m.created_at <= ?");
20217
20231
  whereParams.push(query.createdBefore.getTime());
20218
20232
  }
20219
- const params = [...selectParams, ...whereParams, query.limit];
20233
+ const params = [...whereParams, query.limit];
20220
20234
  const statement = this.database.prepare(`
20221
20235
  SELECT
20222
20236
  m.id,
20223
20237
  m.content,
20224
20238
  m.workspace,
20225
20239
  m.created_at,
20226
- ${scoreExpr} AS score
20240
+ m.updated_at,
20241
+ MAX(0, -bm25(memories_fts)) AS score
20227
20242
  FROM memories_fts
20228
20243
  INNER JOIN memories AS m ON m.rowid = memories_fts.rowid
20229
20244
  WHERE ${whereClauses.join(" AND ")}
@@ -20231,12 +20246,14 @@ class SqliteMemoryRepository {
20231
20246
  LIMIT ?
20232
20247
  `);
20233
20248
  const rows = statement.all(...params);
20249
+ const maxScore = Math.max(...rows.map((row) => row.score), 0);
20234
20250
  return rows.map((row) => ({
20235
20251
  id: row.id,
20236
20252
  content: row.content,
20237
- score: row.score,
20253
+ score: toNormalizedScore(maxScore > 0 ? row.score / maxScore : 0),
20238
20254
  workspace: row.workspace ?? undefined,
20239
- createdAt: new Date(row.created_at)
20255
+ createdAt: new Date(row.created_at),
20256
+ updatedAt: new Date(row.updated_at)
20240
20257
  }));
20241
20258
  } catch (error2) {
20242
20259
  throw new PersistenceError("Failed to search memories.", {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jcyamacho/agent-memory",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.5",
4
+ "version": "0.0.6",
5
5
  "bin": {
6
6
  "agent-memory": "dist/index.js"
7
7
  },