@jcyamacho/agent-memory 0.0.2 → 0.0.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.
- package/README.md +35 -26
- package/dist/index.js +46 -83
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -13,6 +13,18 @@ decisions across sessions.
|
|
|
13
13
|
|
|
14
14
|
## Quick Start
|
|
15
15
|
|
|
16
|
+
Claude CLI:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
claude mcp add --scope user memory -- npx -y @jcyamacho/agent-memory
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Codex CLI:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
codex mcp add memory -- npx -y @jcyamacho/agent-memory
|
|
26
|
+
```
|
|
27
|
+
|
|
16
28
|
Example MCP server config:
|
|
17
29
|
|
|
18
30
|
```json
|
|
@@ -51,22 +63,22 @@ With a custom database path:
|
|
|
51
63
|
Recommended LLM instructions to pair with this MCP:
|
|
52
64
|
|
|
53
65
|
```text
|
|
54
|
-
Use `memory_recall` at
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
Use `memory_remember`
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
`
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
Use `memory_recall` at task start and whenever prior preferences, project facts,
|
|
67
|
+
or decisions may matter.
|
|
68
|
+
|
|
69
|
+
Use `memory_remember` only for durable, reusable context: preferences,
|
|
70
|
+
conventions, decisions, constraints, and stable workflow habits. Store one
|
|
71
|
+
concise, self-contained fact per memory. Include `workspace` when available. Do
|
|
72
|
+
not store secrets or temporary noise.
|
|
73
|
+
|
|
74
|
+
For `memory_recall`, pass `terms` as 2-5 distinctive strings that describe what
|
|
75
|
+
you are looking for. Prefer names, identifiers, package names, file names, and
|
|
76
|
+
short phrases. Each term is matched independently — more terms cast a wider net,
|
|
77
|
+
and results matching multiple terms rank higher. Stemming is applied
|
|
78
|
+
automatically, so exact word forms are not required.
|
|
79
|
+
|
|
80
|
+
Use `preferred_workspace` to bias ranking. Use `filter_workspace` and
|
|
81
|
+
`created_*` only for exact scoping. Keep `limit` small.
|
|
70
82
|
```
|
|
71
83
|
|
|
72
84
|
## What It Stores
|
|
@@ -76,7 +88,7 @@ This MCP is useful for context that should survive across turns and sessions:
|
|
|
76
88
|
- User preferences like response style, formatting, and workflow habits
|
|
77
89
|
- Project facts like paths, architecture choices, and conventions
|
|
78
90
|
- Important decisions and constraints that should not be rediscovered
|
|
79
|
-
-
|
|
91
|
+
- Project-scoped notes that still matter later
|
|
80
92
|
|
|
81
93
|
## Tools
|
|
82
94
|
|
|
@@ -87,16 +99,12 @@ Save durable context for later recall.
|
|
|
87
99
|
Inputs:
|
|
88
100
|
|
|
89
101
|
- `content` -> fact, preference, decision, or context to store
|
|
90
|
-
- `source` -> client, tool, or agent name
|
|
91
102
|
- `workspace` -> repository or workspace path
|
|
92
|
-
- `session` -> conversation or execution session identifier
|
|
93
103
|
|
|
94
104
|
Output:
|
|
95
105
|
|
|
96
106
|
- `id`
|
|
97
|
-
- `source`
|
|
98
107
|
- `workspace`
|
|
99
|
-
- `session`
|
|
100
108
|
- `created_at`
|
|
101
109
|
|
|
102
110
|
### `recall`
|
|
@@ -105,19 +113,17 @@ Retrieve relevant memories for the current task.
|
|
|
105
113
|
|
|
106
114
|
Inputs:
|
|
107
115
|
|
|
108
|
-
- `
|
|
116
|
+
- `terms` -> 2-5 distinctive terms or short phrases that should appear in the
|
|
117
|
+
memory content; avoid full natural-language questions
|
|
109
118
|
- `limit` -> maximum results to return
|
|
110
|
-
- `preferred_source` -> ranking hint for a source
|
|
111
119
|
- `preferred_workspace` -> ranking hint for a workspace
|
|
112
|
-
- `filter_source` -> exact source filter
|
|
113
120
|
- `filter_workspace` -> exact workspace filter
|
|
114
121
|
- `created_after` -> ISO 8601 lower bound
|
|
115
122
|
- `created_before` -> ISO 8601 upper bound
|
|
116
123
|
|
|
117
124
|
Output:
|
|
118
125
|
|
|
119
|
-
- `results[]` with `id`, `content`, `score`, `
|
|
120
|
-
and `created_at`
|
|
126
|
+
- `results[]` with `id`, `content`, `score`, `workspace`, and `created_at`
|
|
121
127
|
|
|
122
128
|
## Setup
|
|
123
129
|
|
|
@@ -150,6 +156,9 @@ Set `AGENT_MEMORY_DB_PATH` when you want to:
|
|
|
150
156
|
- share a memory DB across multiple clients
|
|
151
157
|
- store the DB somewhere easier to back up or inspect
|
|
152
158
|
|
|
159
|
+
Beta note: schema changes are not migrated. If you are upgrading from an older
|
|
160
|
+
beta, delete the existing memory DB and let the server create a new one.
|
|
161
|
+
|
|
153
162
|
## Run from source
|
|
154
163
|
|
|
155
164
|
If you are developing locally instead of using the published package:
|
package/dist/index.js
CHANGED
|
@@ -12464,7 +12464,7 @@ class StdioServerTransport {
|
|
|
12464
12464
|
}
|
|
12465
12465
|
}
|
|
12466
12466
|
// package.json
|
|
12467
|
-
var version2 = "0.0.
|
|
12467
|
+
var version2 = "0.0.3";
|
|
12468
12468
|
|
|
12469
12469
|
// src/config.ts
|
|
12470
12470
|
import { homedir } from "node:os";
|
|
@@ -19932,11 +19932,9 @@ var parseOptionalDate = (value, fieldName) => {
|
|
|
19932
19932
|
|
|
19933
19933
|
// src/tools/recall.ts
|
|
19934
19934
|
var recallInputSchema = {
|
|
19935
|
-
|
|
19935
|
+
terms: array(string2()).min(1).describe("Search terms to match against remembered content. Use distinctive keywords, IDs, names, file names, or short phrases as separate items."),
|
|
19936
19936
|
limit: number2().int().min(1).max(20).optional().describe("Maximum number of memory results to return. Use a small number when you only need the best matches."),
|
|
19937
|
-
preferred_source: string2().optional().describe("Preferred source to rank higher when relevant, such as a client, tool, or agent name. This does not exclude other sources."),
|
|
19938
19937
|
preferred_workspace: string2().optional().describe("Preferred workspace or repository path to rank higher when relevant. This does not exclude other workspaces."),
|
|
19939
|
-
filter_source: string2().optional().describe("Only return memories from this exact source."),
|
|
19940
19938
|
filter_workspace: string2().optional().describe("Only return memories from this exact workspace or repository path."),
|
|
19941
19939
|
created_after: string2().optional().describe("Only return memories created at or after this ISO 8601 timestamp."),
|
|
19942
19940
|
created_before: string2().optional().describe("Only return memories created at or before this ISO 8601 timestamp.")
|
|
@@ -19944,11 +19942,9 @@ var recallInputSchema = {
|
|
|
19944
19942
|
var recallOutputSchema = {
|
|
19945
19943
|
results: array(object({
|
|
19946
19944
|
id: string2().describe("Stable identifier for the remembered item."),
|
|
19947
|
-
content: string2().describe("The remembered content that matched the
|
|
19945
|
+
content: string2().describe("The remembered content that matched the search terms."),
|
|
19948
19946
|
score: number2().describe("Relevance score for this result. Higher means a better match."),
|
|
19949
|
-
source: string2().optional().describe("Source associated with the memory, if available."),
|
|
19950
19947
|
workspace: string2().optional().describe("Workspace associated with the memory, if available."),
|
|
19951
|
-
session: string2().optional().describe("Session associated with the memory, if available."),
|
|
19952
19948
|
created_at: string2().describe("ISO 8601 timestamp showing when the memory was created.")
|
|
19953
19949
|
}))
|
|
19954
19950
|
};
|
|
@@ -19957,23 +19953,12 @@ var registerRecallTool = (server, memoryService) => {
|
|
|
19957
19953
|
description: "Retrieve previously remembered context that may help with the current task. Use it for user preferences, project facts, prior decisions, constraints, or earlier conversation details.",
|
|
19958
19954
|
inputSchema: recallInputSchema,
|
|
19959
19955
|
outputSchema: recallOutputSchema
|
|
19960
|
-
}, async ({
|
|
19961
|
-
query,
|
|
19962
|
-
limit,
|
|
19963
|
-
preferred_source,
|
|
19964
|
-
preferred_workspace,
|
|
19965
|
-
filter_source,
|
|
19966
|
-
filter_workspace,
|
|
19967
|
-
created_after,
|
|
19968
|
-
created_before
|
|
19969
|
-
}) => {
|
|
19956
|
+
}, async ({ terms, limit, preferred_workspace, filter_workspace, created_after, created_before }) => {
|
|
19970
19957
|
try {
|
|
19971
19958
|
const results = await memoryService.search({
|
|
19972
|
-
|
|
19959
|
+
terms,
|
|
19973
19960
|
limit,
|
|
19974
|
-
preferredSource: preferred_source,
|
|
19975
19961
|
preferredWorkspace: preferred_workspace,
|
|
19976
|
-
filterSource: filter_source,
|
|
19977
19962
|
filterWorkspace: filter_workspace,
|
|
19978
19963
|
createdAfter: parseOptionalDate(created_after, "created_after"),
|
|
19979
19964
|
createdBefore: parseOptionalDate(created_before, "created_before")
|
|
@@ -19983,17 +19968,17 @@ var registerRecallTool = (server, memoryService) => {
|
|
|
19983
19968
|
id: result.id,
|
|
19984
19969
|
content: result.content,
|
|
19985
19970
|
score: result.score,
|
|
19986
|
-
source: result.source,
|
|
19987
19971
|
workspace: result.workspace,
|
|
19988
|
-
session: result.session,
|
|
19989
19972
|
created_at: result.createdAt.toISOString()
|
|
19990
19973
|
}))
|
|
19991
19974
|
};
|
|
19975
|
+
const matchCount = structuredContent.results.length;
|
|
19976
|
+
const summary = matchCount === 1 ? "Found 1 matching memory." : `Found ${matchCount} matching memories.`;
|
|
19992
19977
|
return {
|
|
19993
19978
|
content: [
|
|
19994
19979
|
{
|
|
19995
19980
|
type: "text",
|
|
19996
|
-
text:
|
|
19981
|
+
text: summary
|
|
19997
19982
|
}
|
|
19998
19983
|
],
|
|
19999
19984
|
structuredContent
|
|
@@ -20007,15 +19992,11 @@ var registerRecallTool = (server, memoryService) => {
|
|
|
20007
19992
|
// src/tools/remember.ts
|
|
20008
19993
|
var rememberInputSchema = {
|
|
20009
19994
|
content: string2().describe("The exact fact, preference, decision, or context to remember for future retrieval. Use a self-contained sentence or short note."),
|
|
20010
|
-
|
|
20011
|
-
workspace: string2().optional().describe("Repository or workspace path this memory belongs to. Use it to keep memories scoped to a project."),
|
|
20012
|
-
session: string2().optional().describe("Conversation or execution session identifier. Useful for tying memories back to one run or thread.")
|
|
19995
|
+
workspace: string2().optional().describe("Repository or workspace path this memory belongs to. Use it to keep memories scoped to a project.")
|
|
20013
19996
|
};
|
|
20014
19997
|
var rememberOutputSchema = {
|
|
20015
19998
|
id: string2().describe("Stable identifier for the saved memory."),
|
|
20016
|
-
source: string2().optional().describe("Source stored with the memory, if provided."),
|
|
20017
19999
|
workspace: string2().optional().describe("Workspace stored with the memory, if provided."),
|
|
20018
|
-
session: string2().optional().describe("Session stored with the memory, if provided."),
|
|
20019
20000
|
created_at: string2().describe("ISO 8601 timestamp showing when the memory was created.")
|
|
20020
20001
|
};
|
|
20021
20002
|
var registerRememberTool = (server, memoryService) => {
|
|
@@ -20023,26 +20004,22 @@ var registerRememberTool = (server, memoryService) => {
|
|
|
20023
20004
|
description: "Save durable context for later recall. Use this for user preferences, project facts, decisions, constraints, or other information worth remembering across turns and tools.",
|
|
20024
20005
|
inputSchema: rememberInputSchema,
|
|
20025
20006
|
outputSchema: rememberOutputSchema
|
|
20026
|
-
}, async ({ content,
|
|
20007
|
+
}, async ({ content, workspace }) => {
|
|
20027
20008
|
try {
|
|
20028
20009
|
const memory = await memoryService.save({
|
|
20029
20010
|
content,
|
|
20030
|
-
|
|
20031
|
-
workspace,
|
|
20032
|
-
session
|
|
20011
|
+
workspace
|
|
20033
20012
|
});
|
|
20034
20013
|
const structuredContent = {
|
|
20035
20014
|
id: memory.id,
|
|
20036
|
-
source: memory.source,
|
|
20037
20015
|
workspace: memory.workspace,
|
|
20038
|
-
session: memory.session,
|
|
20039
20016
|
created_at: memory.createdAt.toISOString()
|
|
20040
20017
|
};
|
|
20041
20018
|
return {
|
|
20042
20019
|
content: [
|
|
20043
20020
|
{
|
|
20044
20021
|
type: "text",
|
|
20045
|
-
text:
|
|
20022
|
+
text: "Saved memory."
|
|
20046
20023
|
}
|
|
20047
20024
|
],
|
|
20048
20025
|
structuredContent
|
|
@@ -20068,8 +20045,6 @@ var createMcpServer = (memoryService, version3) => {
|
|
|
20068
20045
|
import { randomUUID } from "node:crypto";
|
|
20069
20046
|
var DEFAULT_LIMIT = 5;
|
|
20070
20047
|
var MAX_LIMIT = 20;
|
|
20071
|
-
var SOURCE_BIAS = 0.15;
|
|
20072
|
-
var WORKSPACE_BIAS = 0.1;
|
|
20073
20048
|
|
|
20074
20049
|
class MemoryService {
|
|
20075
20050
|
repository;
|
|
@@ -20085,34 +20060,27 @@ class MemoryService {
|
|
|
20085
20060
|
const memory = {
|
|
20086
20061
|
id: randomUUID(),
|
|
20087
20062
|
content,
|
|
20088
|
-
source: normalizeOptionalString(input.source),
|
|
20089
20063
|
workspace: normalizeOptionalString(input.workspace),
|
|
20090
|
-
session: normalizeOptionalString(input.session),
|
|
20091
20064
|
createdAt: now,
|
|
20092
20065
|
updatedAt: now
|
|
20093
20066
|
};
|
|
20094
20067
|
return this.repository.save(memory);
|
|
20095
20068
|
}
|
|
20096
20069
|
async search(input) {
|
|
20097
|
-
const
|
|
20098
|
-
if (
|
|
20099
|
-
throw new ValidationError("
|
|
20070
|
+
const terms = normalizeTerms(input.terms);
|
|
20071
|
+
if (terms.length === 0) {
|
|
20072
|
+
throw new ValidationError("At least one search term is required.");
|
|
20100
20073
|
}
|
|
20101
20074
|
const normalizedQuery = {
|
|
20102
|
-
|
|
20075
|
+
terms,
|
|
20103
20076
|
limit: normalizeLimit(input.limit),
|
|
20104
|
-
preferredSource: normalizeOptionalString(input.preferredSource),
|
|
20105
20077
|
preferredWorkspace: normalizeOptionalString(input.preferredWorkspace),
|
|
20106
|
-
filterSource: normalizeOptionalString(input.filterSource),
|
|
20107
20078
|
filterWorkspace: normalizeOptionalString(input.filterWorkspace),
|
|
20108
20079
|
createdAfter: input.createdAfter,
|
|
20109
20080
|
createdBefore: input.createdBefore
|
|
20110
20081
|
};
|
|
20111
20082
|
const results = await this.repository.search(normalizedQuery);
|
|
20112
|
-
return results.
|
|
20113
|
-
...result,
|
|
20114
|
-
score: rankResult(result, normalizedQuery)
|
|
20115
|
-
})).sort((left, right) => right.score - left.score).slice(0, normalizedQuery.limit);
|
|
20083
|
+
return results.slice(0, normalizedQuery.limit);
|
|
20116
20084
|
}
|
|
20117
20085
|
}
|
|
20118
20086
|
var normalizeLimit = (value) => {
|
|
@@ -20128,15 +20096,9 @@ var normalizeOptionalString = (value) => {
|
|
|
20128
20096
|
const trimmed = value?.trim();
|
|
20129
20097
|
return trimmed ? trimmed : undefined;
|
|
20130
20098
|
};
|
|
20131
|
-
var
|
|
20132
|
-
|
|
20133
|
-
|
|
20134
|
-
score += SOURCE_BIAS;
|
|
20135
|
-
}
|
|
20136
|
-
if (query.preferredWorkspace && result.workspace === query.preferredWorkspace) {
|
|
20137
|
-
score += WORKSPACE_BIAS;
|
|
20138
|
-
}
|
|
20139
|
-
return Number(score.toFixed(6));
|
|
20099
|
+
var normalizeTerms = (terms) => {
|
|
20100
|
+
const normalizedTerms = terms.map((term) => term.trim()).filter(Boolean);
|
|
20101
|
+
return [...new Set(normalizedTerms)];
|
|
20140
20102
|
};
|
|
20141
20103
|
|
|
20142
20104
|
// src/sqlite-db.ts
|
|
@@ -20147,22 +20109,19 @@ var MEMORY_SCHEMA = `
|
|
|
20147
20109
|
CREATE TABLE IF NOT EXISTS memories (
|
|
20148
20110
|
id TEXT PRIMARY KEY,
|
|
20149
20111
|
content TEXT NOT NULL,
|
|
20150
|
-
source TEXT,
|
|
20151
20112
|
workspace TEXT,
|
|
20152
|
-
session TEXT,
|
|
20153
20113
|
created_at INTEGER NOT NULL,
|
|
20154
20114
|
updated_at INTEGER NOT NULL
|
|
20155
20115
|
);
|
|
20156
20116
|
|
|
20157
20117
|
CREATE INDEX IF NOT EXISTS idx_memories_created_at ON memories(created_at);
|
|
20158
|
-
CREATE INDEX IF NOT EXISTS idx_memories_source ON memories(source);
|
|
20159
20118
|
CREATE INDEX IF NOT EXISTS idx_memories_workspace ON memories(workspace);
|
|
20160
20119
|
|
|
20161
20120
|
CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
|
|
20162
20121
|
content,
|
|
20163
20122
|
content = 'memories',
|
|
20164
20123
|
content_rowid = 'rowid',
|
|
20165
|
-
tokenize = 'unicode61'
|
|
20124
|
+
tokenize = 'porter unicode61'
|
|
20166
20125
|
);
|
|
20167
20126
|
|
|
20168
20127
|
CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
|
|
@@ -20211,6 +20170,7 @@ var initializeMemoryDatabase = (database) => {
|
|
|
20211
20170
|
var CANDIDATE_MULTIPLIER = 5;
|
|
20212
20171
|
var MIN_CANDIDATES = 25;
|
|
20213
20172
|
var MAX_CANDIDATES = 100;
|
|
20173
|
+
var WORKSPACE_BIAS = 0.1;
|
|
20214
20174
|
|
|
20215
20175
|
class SqliteMemoryRepository {
|
|
20216
20176
|
database;
|
|
@@ -20221,9 +20181,7 @@ class SqliteMemoryRepository {
|
|
|
20221
20181
|
INSERT INTO memories (
|
|
20222
20182
|
id,
|
|
20223
20183
|
content,
|
|
20224
|
-
source,
|
|
20225
20184
|
workspace,
|
|
20226
|
-
session,
|
|
20227
20185
|
created_at,
|
|
20228
20186
|
updated_at
|
|
20229
20187
|
) VALUES (
|
|
@@ -20231,15 +20189,13 @@ class SqliteMemoryRepository {
|
|
|
20231
20189
|
?,
|
|
20232
20190
|
?,
|
|
20233
20191
|
?,
|
|
20234
|
-
?,
|
|
20235
|
-
?,
|
|
20236
20192
|
?
|
|
20237
20193
|
)
|
|
20238
20194
|
`);
|
|
20239
20195
|
}
|
|
20240
20196
|
async save(memory) {
|
|
20241
20197
|
try {
|
|
20242
|
-
this.insertStatement.run(memory.id, memory.content, memory.
|
|
20198
|
+
this.insertStatement.run(memory.id, memory.content, memory.workspace, memory.createdAt.getTime(), memory.updatedAt.getTime());
|
|
20243
20199
|
return memory;
|
|
20244
20200
|
} catch (error2) {
|
|
20245
20201
|
throw new PersistenceError("Failed to save memory.", { cause: error2 });
|
|
@@ -20247,48 +20203,48 @@ class SqliteMemoryRepository {
|
|
|
20247
20203
|
}
|
|
20248
20204
|
async search(query) {
|
|
20249
20205
|
try {
|
|
20250
|
-
const
|
|
20251
|
-
const
|
|
20252
|
-
|
|
20253
|
-
|
|
20254
|
-
|
|
20206
|
+
const selectParams = [];
|
|
20207
|
+
const whereParams = [toFtsQuery(query.terms)];
|
|
20208
|
+
let scoreExpr;
|
|
20209
|
+
if (query.preferredWorkspace) {
|
|
20210
|
+
scoreExpr = "MAX(0, -bm25(memories_fts) + CASE WHEN m.workspace = ? THEN ? ELSE 0.0 END)";
|
|
20211
|
+
selectParams.push(query.preferredWorkspace, WORKSPACE_BIAS);
|
|
20212
|
+
} else {
|
|
20213
|
+
scoreExpr = "MAX(0, -bm25(memories_fts))";
|
|
20255
20214
|
}
|
|
20215
|
+
const whereClauses = ["memories_fts MATCH ?"];
|
|
20256
20216
|
if (query.filterWorkspace) {
|
|
20257
20217
|
whereClauses.push("m.workspace = ?");
|
|
20258
|
-
|
|
20218
|
+
whereParams.push(query.filterWorkspace);
|
|
20259
20219
|
}
|
|
20260
20220
|
if (query.createdAfter) {
|
|
20261
20221
|
whereClauses.push("m.created_at >= ?");
|
|
20262
|
-
|
|
20222
|
+
whereParams.push(query.createdAfter.getTime());
|
|
20263
20223
|
}
|
|
20264
20224
|
if (query.createdBefore) {
|
|
20265
20225
|
whereClauses.push("m.created_at <= ?");
|
|
20266
|
-
|
|
20226
|
+
whereParams.push(query.createdBefore.getTime());
|
|
20267
20227
|
}
|
|
20228
|
+
const params = [...selectParams, ...whereParams, toCandidateLimit(query.limit)];
|
|
20268
20229
|
const statement = this.database.prepare(`
|
|
20269
20230
|
SELECT
|
|
20270
20231
|
m.id,
|
|
20271
20232
|
m.content,
|
|
20272
|
-
m.source,
|
|
20273
20233
|
m.workspace,
|
|
20274
|
-
m.session,
|
|
20275
20234
|
m.created_at,
|
|
20276
|
-
|
|
20235
|
+
${scoreExpr} AS score
|
|
20277
20236
|
FROM memories_fts
|
|
20278
20237
|
INNER JOIN memories AS m ON m.rowid = memories_fts.rowid
|
|
20279
20238
|
WHERE ${whereClauses.join(" AND ")}
|
|
20280
|
-
ORDER BY
|
|
20239
|
+
ORDER BY score DESC
|
|
20281
20240
|
LIMIT ?
|
|
20282
20241
|
`);
|
|
20283
|
-
params.push(toCandidateLimit(query.limit));
|
|
20284
20242
|
const rows = statement.all(...params);
|
|
20285
20243
|
return rows.map((row) => ({
|
|
20286
20244
|
id: row.id,
|
|
20287
20245
|
content: row.content,
|
|
20288
20246
|
score: row.score,
|
|
20289
|
-
source: row.source ?? undefined,
|
|
20290
20247
|
workspace: row.workspace ?? undefined,
|
|
20291
|
-
session: row.session ?? undefined,
|
|
20292
20248
|
createdAt: new Date(row.created_at)
|
|
20293
20249
|
}));
|
|
20294
20250
|
} catch (error2) {
|
|
@@ -20299,7 +20255,14 @@ class SqliteMemoryRepository {
|
|
|
20299
20255
|
}
|
|
20300
20256
|
}
|
|
20301
20257
|
var toCandidateLimit = (limit) => Math.min(Math.max(limit * CANDIDATE_MULTIPLIER, MIN_CANDIDATES), MAX_CANDIDATES);
|
|
20302
|
-
var toFtsQuery = (
|
|
20258
|
+
var toFtsQuery = (terms) => terms.map(toFtsTerm).join(" OR ");
|
|
20259
|
+
var toFtsTerm = (term) => {
|
|
20260
|
+
const escaped = term.replaceAll('"', '""');
|
|
20261
|
+
if (term.includes(" ")) {
|
|
20262
|
+
return `"${escaped}"`;
|
|
20263
|
+
}
|
|
20264
|
+
return `"${escaped}"*`;
|
|
20265
|
+
};
|
|
20303
20266
|
|
|
20304
20267
|
// src/index.ts
|
|
20305
20268
|
var { databasePath } = resolveConfig();
|
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.
|
|
4
|
+
"version": "0.0.3",
|
|
5
5
|
"bin": {
|
|
6
6
|
"agent-memory": "dist/index.js"
|
|
7
7
|
},
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"build": "bun build src/index.ts --target=node --external better-sqlite3 --outfile dist/index.js --banner \"#!/usr/bin/env node\"",
|
|
24
24
|
"start": "node dist/index.js",
|
|
25
25
|
"test": "bun test",
|
|
26
|
-
"lint": "biome check --write",
|
|
26
|
+
"lint": "biome check --write && tsc --noEmit",
|
|
27
27
|
"release:patch": "npm version patch && git push origin main --follow-tags",
|
|
28
28
|
"release:minor": "npm version minor && git push origin main --follow-tags",
|
|
29
29
|
"release:major": "npm version major && git push origin main --follow-tags"
|