@hanhnd/agent-kit 1.0.34 → 1.0.35
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/dist/cli/commands/cli-digest-pending.test.js +19 -10
- package/dist/cli/commands/memory.js +44 -4
- package/dist/cli.js +307 -129
- package/dist/core/config/index.d.ts +3 -0
- package/dist/core/config/index.js +20 -0
- package/dist/entrypoints/server.js +1 -3
- package/dist/mcp/memory.d.ts +2 -1
- package/dist/mcp/memory.js +45 -18
- package/dist/server.js +253 -150
- package/dist/services/digest/constants.d.ts +3 -3
- package/dist/services/digest/constants.js +3 -3
- package/dist/services/digest/digest-background.test.js +19 -8
- package/dist/services/digest/digest-init.test.js +13 -2
- package/dist/services/digest/digest-pending.test.js +13 -2
- package/dist/services/digest/digest-processor.test.js +66 -0
- package/dist/services/digest/files.js +3 -3
- package/dist/services/digest/model-registry.js +2 -2
- package/dist/services/digest/processor.js +43 -13
- package/dist/services/digest/providers/llama-local.js +17 -28
- package/dist/services/digest/types.d.ts +3 -1
- package/dist/services/digest/types.js +1 -1
- package/dist/services/memory/chunker.d.ts +5 -2
- package/dist/services/memory/chunker.js +3 -1
- package/dist/services/memory/chunker.test.js +21 -11
- package/dist/services/memory/constants.js +1 -1
- package/dist/services/memory/embedder.js +1 -1
- package/dist/services/memory/index.d.ts +1 -1
- package/dist/services/memory/indexer.d.ts +2 -1
- package/dist/services/memory/indexer.js +24 -8
- package/dist/services/memory/indexer.test.js +38 -2
- package/dist/services/memory/memory.test.js +172 -15
- package/dist/services/memory/store.d.ts +6 -1
- package/dist/services/memory/store.js +87 -47
- package/dist/services/memory/store.test.js +123 -3
- package/dist/services/memory/types.d.ts +9 -1
- package/dist/services/memory/types.js +2 -1
- package/dist/utils/paths.d.ts +2 -0
- package/dist/utils/paths.js +2 -1
- package/dist/utils/utils.d.ts +1 -0
- package/dist/utils/utils.js +3 -3
- package/package.json +2 -2
package/dist/server.js
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
3
2
|
var __create = Object.create;
|
|
4
3
|
var __defProp = Object.defineProperty;
|
|
5
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var
|
|
10
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
11
|
-
}) : x)(function(x) {
|
|
12
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
13
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
14
|
-
});
|
|
15
|
-
var __commonJS = (cb, mod) => function __require2() {
|
|
8
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
16
9
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
17
10
|
};
|
|
18
11
|
var __export = (target, all) => {
|
|
@@ -6792,12 +6785,12 @@ var require_dist = __commonJS({
|
|
|
6792
6785
|
throw new Error(`Unknown format "${name}"`);
|
|
6793
6786
|
return f;
|
|
6794
6787
|
};
|
|
6795
|
-
function addFormats(ajv, list,
|
|
6788
|
+
function addFormats(ajv, list, fs12, exportName) {
|
|
6796
6789
|
var _a;
|
|
6797
6790
|
var _b;
|
|
6798
6791
|
(_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
6799
6792
|
for (const f of list)
|
|
6800
|
-
ajv.addFormat(f,
|
|
6793
|
+
ajv.addFormat(f, fs12[f]);
|
|
6801
6794
|
}
|
|
6802
6795
|
module.exports = exports = formatsPlugin;
|
|
6803
6796
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -35889,7 +35882,7 @@ import * as path4 from "path";
|
|
|
35889
35882
|
|
|
35890
35883
|
// src/utils/utils.ts
|
|
35891
35884
|
function getWorkspaceRoot() {
|
|
35892
|
-
return process.env.WORKSPACE_DIR || process.env.CLAUDE_PROJECT_DIR || process.env.CODEX_PROJECT_DIR || process.env.GEMINI_PROJECT_DIR || process.env.
|
|
35885
|
+
return process.env.WORKSPACE_DIR || process.env.CLAUDE_PROJECT_DIR || process.env.CODEX_PROJECT_DIR || process.env.GEMINI_PROJECT_DIR || process.env.INIT_CWD || process.env.PWD || process.cwd();
|
|
35893
35886
|
}
|
|
35894
35887
|
function mcpText(text) {
|
|
35895
35888
|
return { content: [{ type: "text", text }] };
|
|
@@ -35897,11 +35890,18 @@ function mcpText(text) {
|
|
|
35897
35890
|
function mcpJson(obj) {
|
|
35898
35891
|
return mcpText(JSON.stringify(obj, null, 2));
|
|
35899
35892
|
}
|
|
35893
|
+
function formatError2(err) {
|
|
35894
|
+
return err instanceof Error ? err.message : String(err);
|
|
35895
|
+
}
|
|
35900
35896
|
|
|
35901
35897
|
// src/core/config/index.ts
|
|
35902
35898
|
import * as fs2 from "fs";
|
|
35899
|
+
import * as os from "os";
|
|
35903
35900
|
import * as path2 from "path";
|
|
35904
35901
|
|
|
35902
|
+
// src/services/memory/types.ts
|
|
35903
|
+
var SOURCE_TYPES = ["digest", "concept", "entity", "preference", "wiki"];
|
|
35904
|
+
|
|
35905
35905
|
// src/services/memory/constants.ts
|
|
35906
35906
|
var DEFAULT_MEMORY_CONFIG = {
|
|
35907
35907
|
enabled: false,
|
|
@@ -35909,7 +35909,7 @@ var DEFAULT_MEMORY_CONFIG = {
|
|
|
35909
35909
|
topK: 5,
|
|
35910
35910
|
chunkSize: 1500,
|
|
35911
35911
|
overlapLines: 2,
|
|
35912
|
-
embeddingModel: "
|
|
35912
|
+
embeddingModel: "base" /* BASE */,
|
|
35913
35913
|
vectorDimension: 384
|
|
35914
35914
|
};
|
|
35915
35915
|
var LOCK_RETRY_MS = 50;
|
|
@@ -35983,8 +35983,8 @@ function tryAcquireProcessLock(lockPath) {
|
|
|
35983
35983
|
}
|
|
35984
35984
|
|
|
35985
35985
|
// src/core/config/index.ts
|
|
35986
|
-
function resolveMemoryConfig(
|
|
35987
|
-
const override =
|
|
35986
|
+
function resolveMemoryConfig(settings, workspaceRoot2) {
|
|
35987
|
+
const override = settings.memory ?? {};
|
|
35988
35988
|
return {
|
|
35989
35989
|
...DEFAULT_MEMORY_CONFIG,
|
|
35990
35990
|
...override,
|
|
@@ -35992,24 +35992,26 @@ function resolveMemoryConfig(settings2, workspaceRoot2) {
|
|
|
35992
35992
|
wikiDir: typeof override.wikiDir === "string" && override.wikiDir.length > 0 ? override.wikiDir : path2.join(workspaceRoot2, ".agent-kit", "wiki")
|
|
35993
35993
|
};
|
|
35994
35994
|
}
|
|
35995
|
-
function
|
|
35996
|
-
|
|
35997
|
-
|
|
35995
|
+
function getGlobalSettingsFile() {
|
|
35996
|
+
return path2.join(os.homedir(), ".agent-kit", "settings.json");
|
|
35997
|
+
}
|
|
35998
|
+
function loadGlobalSettings() {
|
|
35999
|
+
const file = getGlobalSettingsFile();
|
|
36000
|
+
if (fs2.existsSync(file)) {
|
|
35998
36001
|
try {
|
|
35999
|
-
return JSON.parse(fs2.readFileSync(
|
|
36002
|
+
return JSON.parse(fs2.readFileSync(file, "utf-8"));
|
|
36000
36003
|
} catch (error2) {
|
|
36001
|
-
console.error(`[agent-kit] Warning: Failed to parse ${
|
|
36004
|
+
console.error(`[agent-kit] Warning: Failed to parse ${file}:`, error2);
|
|
36002
36005
|
}
|
|
36003
36006
|
}
|
|
36004
36007
|
return {};
|
|
36005
36008
|
}
|
|
36006
|
-
function
|
|
36007
|
-
const
|
|
36008
|
-
|
|
36009
|
-
atomicWriteJsonFile(settingsPath, { ...current, ...patch });
|
|
36009
|
+
function writeGlobalSettings(patch) {
|
|
36010
|
+
const current = loadGlobalSettings();
|
|
36011
|
+
atomicWriteJsonFile(getGlobalSettingsFile(), { ...current, ...patch });
|
|
36010
36012
|
}
|
|
36011
|
-
function resolveConversationDigestConfig(
|
|
36012
|
-
const digest =
|
|
36013
|
+
function resolveConversationDigestConfig(settings) {
|
|
36014
|
+
const digest = settings.memory?.conversationDigest;
|
|
36013
36015
|
if (!digest?.initialized || typeof digest.modelId !== "string" || typeof digest.initializedAt !== "string") {
|
|
36014
36016
|
return void 0;
|
|
36015
36017
|
}
|
|
@@ -36383,10 +36385,11 @@ import { writeFileSync as writeFileSync4 } from "fs";
|
|
|
36383
36385
|
import * as fs5 from "fs";
|
|
36384
36386
|
|
|
36385
36387
|
// src/utils/paths.ts
|
|
36386
|
-
import * as
|
|
36388
|
+
import * as os2 from "os";
|
|
36387
36389
|
import * as path7 from "path";
|
|
36388
|
-
var AGENT_KIT_HOME = path7.join(
|
|
36390
|
+
var AGENT_KIT_HOME = path7.join(os2.homedir(), ".agent-kit");
|
|
36389
36391
|
var CREDENTIALS_FILE = path7.join(AGENT_KIT_HOME, "credentials");
|
|
36392
|
+
var GLOBAL_SETTINGS_FILE = path7.join(AGENT_KIT_HOME, "settings.json");
|
|
36390
36393
|
var MODEL_CACHE_DIR = path7.join(AGENT_KIT_HOME, "cache", "models");
|
|
36391
36394
|
var FASTEMBED_CACHE_DIR = path7.join(MODEL_CACHE_DIR, "fastembed");
|
|
36392
36395
|
|
|
@@ -36758,6 +36761,7 @@ ${ticket.fields.labels?.join(", ") || "None"}`;
|
|
|
36758
36761
|
}
|
|
36759
36762
|
|
|
36760
36763
|
// src/mcp/memory.ts
|
|
36764
|
+
import * as fs11 from "fs";
|
|
36761
36765
|
import * as path14 from "path";
|
|
36762
36766
|
|
|
36763
36767
|
// src/services/memory/embedder.ts
|
|
@@ -36807,7 +36811,7 @@ var Embedder = class {
|
|
|
36807
36811
|
const { EmbeddingModel, FlagEmbedding } = await import("fastembed");
|
|
36808
36812
|
const modelMap = {
|
|
36809
36813
|
["tiny" /* TINY */]: EmbeddingModel.AllMiniLML6V2,
|
|
36810
|
-
["
|
|
36814
|
+
["base" /* BASE */]: EmbeddingModel.BGESmallENV15,
|
|
36811
36815
|
["large" /* LARGE */]: EmbeddingModel.BGEBaseENV15
|
|
36812
36816
|
};
|
|
36813
36817
|
const model = modelMap[this.modelName] ?? EmbeddingModel.BGESmallENV15;
|
|
@@ -36919,7 +36923,7 @@ function splitSection(text, maxLen) {
|
|
|
36919
36923
|
if (byPara.every((p) => p.length <= maxLen)) return byPara;
|
|
36920
36924
|
return byPara.flatMap((p) => p.length <= maxLen ? [p] : splitAtLine(p, maxLen));
|
|
36921
36925
|
}
|
|
36922
|
-
function chunkMarkdown(text, source, config2) {
|
|
36926
|
+
function chunkMarkdown(text, source, config2, meta) {
|
|
36923
36927
|
if (!text || !text.trim()) return [];
|
|
36924
36928
|
const { chunkSize, overlapLines } = config2;
|
|
36925
36929
|
const lines = text.split("\n");
|
|
@@ -36958,11 +36962,13 @@ ${sectionText}` : sectionText;
|
|
|
36958
36962
|
chunks.push({
|
|
36959
36963
|
id: computeChunkId(content),
|
|
36960
36964
|
source,
|
|
36965
|
+
sourceType: meta.sourceType,
|
|
36961
36966
|
heading: section.heading,
|
|
36962
36967
|
headingLevel: section.headingLevel,
|
|
36963
36968
|
content,
|
|
36964
36969
|
lineStart: firstLine,
|
|
36965
|
-
lineEnd: lastLine
|
|
36970
|
+
lineEnd: lastLine,
|
|
36971
|
+
fileMtimeAt: meta.fileMtimeAt
|
|
36966
36972
|
});
|
|
36967
36973
|
if (pi === parts.length - 1) {
|
|
36968
36974
|
prevOverlapLines = partLines.slice(-overlapLines);
|
|
@@ -36973,6 +36979,13 @@ ${sectionText}` : sectionText;
|
|
|
36973
36979
|
}
|
|
36974
36980
|
|
|
36975
36981
|
// src/services/memory/indexer.ts
|
|
36982
|
+
function deriveSourceType(source) {
|
|
36983
|
+
if (source.startsWith("compiled/provisional/conversation-digests/")) return "digest";
|
|
36984
|
+
if (source.startsWith("compiled/concepts/")) return "concept";
|
|
36985
|
+
if (source.startsWith("compiled/entities/")) return "entity";
|
|
36986
|
+
if (source === "compiled/preferences.md") return "preference";
|
|
36987
|
+
return "wiki";
|
|
36988
|
+
}
|
|
36976
36989
|
var MemoryIndexer = class {
|
|
36977
36990
|
constructor(store, embedder, config2) {
|
|
36978
36991
|
this.store = store;
|
|
@@ -36993,7 +37006,15 @@ var MemoryIndexer = class {
|
|
|
36993
37006
|
console.warn(`[memory-indexer] Cannot read file ${absolutePath}:`, err);
|
|
36994
37007
|
return { indexed: 0, deleted: 0, skipped: existingChunkIds.size };
|
|
36995
37008
|
}
|
|
36996
|
-
|
|
37009
|
+
let fileMtimeAt;
|
|
37010
|
+
try {
|
|
37011
|
+
fileMtimeAt = fs6.statSync(absolutePath).mtimeMs;
|
|
37012
|
+
} catch (err) {
|
|
37013
|
+
console.warn(`[memory-indexer] Cannot stat file ${absolutePath}:`, err);
|
|
37014
|
+
fileMtimeAt = Date.now();
|
|
37015
|
+
}
|
|
37016
|
+
const sourceType = deriveSourceType(source);
|
|
37017
|
+
const allChunks = chunkMarkdown(text, source, this.config, { sourceType, fileMtimeAt });
|
|
36997
37018
|
const currentChunkIds = new Set(allChunks.map((chunk) => chunk.id));
|
|
36998
37019
|
const toIndex = allChunks.filter((chunk) => !existingChunkIds.has(chunk.id));
|
|
36999
37020
|
const toDelete = [...existingChunkIds].filter((id) => !currentChunkIds.has(id));
|
|
@@ -37080,12 +37101,9 @@ var MemoryIndexer = class {
|
|
|
37080
37101
|
scoreMap.set(r.id, { dense: 1 / (RRF_K + rank + 1), bm25: 0 });
|
|
37081
37102
|
});
|
|
37082
37103
|
bm25Results.forEach((r, rank) => {
|
|
37083
|
-
const
|
|
37084
|
-
|
|
37085
|
-
|
|
37086
|
-
} else {
|
|
37087
|
-
scoreMap.set(r.id, { dense: 0, bm25: 1 / (RRF_K + rank + 1) });
|
|
37088
|
-
}
|
|
37104
|
+
const entry = scoreMap.get(r.id) ?? { dense: 0, bm25: 0 };
|
|
37105
|
+
entry.bm25 = 1 / (RRF_K + rank + 1);
|
|
37106
|
+
scoreMap.set(r.id, entry);
|
|
37089
37107
|
});
|
|
37090
37108
|
const hasDense = this.store.vecAvailable && denseResults.length > 0;
|
|
37091
37109
|
const numRetrievers = hasDense ? 2 : 1;
|
|
@@ -37159,7 +37177,10 @@ ${content}
|
|
|
37159
37177
|
var import_stopword = __toESM(require_stopword_cjs(), 1);
|
|
37160
37178
|
import Database from "better-sqlite3";
|
|
37161
37179
|
import * as fs7 from "fs";
|
|
37180
|
+
import { createRequire } from "module";
|
|
37162
37181
|
import * as path9 from "path";
|
|
37182
|
+
var require2 = createRequire(import.meta.url);
|
|
37183
|
+
var SCHEMA_VERSION = 2;
|
|
37163
37184
|
var StoreError = class extends Error {
|
|
37164
37185
|
constructor(message, cause) {
|
|
37165
37186
|
super(message);
|
|
@@ -37199,7 +37220,7 @@ var MemoryStore = class {
|
|
|
37199
37220
|
}
|
|
37200
37221
|
loadVecExtension(db) {
|
|
37201
37222
|
try {
|
|
37202
|
-
const sqliteVec =
|
|
37223
|
+
const sqliteVec = require2("sqlite-vec");
|
|
37203
37224
|
sqliteVec.load(db);
|
|
37204
37225
|
this._vecAvailable = true;
|
|
37205
37226
|
} catch (err) {
|
|
@@ -37208,57 +37229,77 @@ var MemoryStore = class {
|
|
|
37208
37229
|
}
|
|
37209
37230
|
}
|
|
37210
37231
|
createSchema(db) {
|
|
37211
|
-
|
|
37212
|
-
|
|
37213
|
-
|
|
37214
|
-
|
|
37215
|
-
|
|
37216
|
-
|
|
37217
|
-
|
|
37218
|
-
|
|
37219
|
-
|
|
37220
|
-
|
|
37221
|
-
|
|
37222
|
-
|
|
37232
|
+
try {
|
|
37233
|
+
const current = Number(db.pragma("user_version", { simple: true }) ?? 0);
|
|
37234
|
+
if (current < SCHEMA_VERSION) {
|
|
37235
|
+
db.exec(`
|
|
37236
|
+
DROP TRIGGER IF EXISTS memory_chunks_ai;
|
|
37237
|
+
DROP TRIGGER IF EXISTS memory_chunks_ad;
|
|
37238
|
+
DROP TABLE IF EXISTS memory_fts;
|
|
37239
|
+
DROP TABLE IF EXISTS memory_vec;
|
|
37240
|
+
DROP TABLE IF EXISTS memory_chunks;
|
|
37241
|
+
`);
|
|
37242
|
+
db.pragma(`user_version = ${SCHEMA_VERSION}`);
|
|
37243
|
+
}
|
|
37244
|
+
db.exec(`
|
|
37245
|
+
CREATE TABLE IF NOT EXISTS memory_chunks (
|
|
37246
|
+
rowid INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
37247
|
+
id TEXT NOT NULL UNIQUE,
|
|
37248
|
+
source TEXT NOT NULL,
|
|
37249
|
+
source_type TEXT NOT NULL DEFAULT 'wiki',
|
|
37250
|
+
heading TEXT NOT NULL DEFAULT '',
|
|
37251
|
+
heading_level INTEGER NOT NULL DEFAULT 0,
|
|
37252
|
+
content TEXT NOT NULL,
|
|
37253
|
+
line_start INTEGER NOT NULL,
|
|
37254
|
+
line_end INTEGER NOT NULL,
|
|
37255
|
+
indexed_at INTEGER NOT NULL,
|
|
37256
|
+
file_mtime_at INTEGER NOT NULL DEFAULT 0
|
|
37257
|
+
);
|
|
37223
37258
|
|
|
37224
|
-
|
|
37225
|
-
|
|
37226
|
-
heading,
|
|
37227
|
-
content,
|
|
37228
|
-
content='memory_chunks',
|
|
37229
|
-
content_rowid='rowid'
|
|
37230
|
-
);
|
|
37259
|
+
CREATE INDEX IF NOT EXISTS idx_memory_chunks_type_mtime
|
|
37260
|
+
ON memory_chunks (source_type, file_mtime_at DESC);
|
|
37231
37261
|
|
|
37232
|
-
|
|
37233
|
-
|
|
37234
|
-
|
|
37235
|
-
|
|
37236
|
-
|
|
37262
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS memory_fts USING fts5(
|
|
37263
|
+
source,
|
|
37264
|
+
heading,
|
|
37265
|
+
content,
|
|
37266
|
+
content='memory_chunks',
|
|
37267
|
+
content_rowid='rowid'
|
|
37268
|
+
);
|
|
37237
37269
|
|
|
37238
|
-
|
|
37239
|
-
|
|
37240
|
-
|
|
37241
|
-
|
|
37242
|
-
|
|
37243
|
-
|
|
37244
|
-
|
|
37245
|
-
|
|
37246
|
-
|
|
37247
|
-
|
|
37248
|
-
|
|
37249
|
-
|
|
37250
|
-
|
|
37251
|
-
|
|
37252
|
-
|
|
37253
|
-
|
|
37270
|
+
CREATE TRIGGER IF NOT EXISTS memory_chunks_ai
|
|
37271
|
+
AFTER INSERT ON memory_chunks BEGIN
|
|
37272
|
+
INSERT INTO memory_fts(rowid, source, heading, content)
|
|
37273
|
+
VALUES (new.rowid, new.source, new.heading, new.content);
|
|
37274
|
+
END;
|
|
37275
|
+
|
|
37276
|
+
CREATE TRIGGER IF NOT EXISTS memory_chunks_ad
|
|
37277
|
+
AFTER DELETE ON memory_chunks BEGIN
|
|
37278
|
+
INSERT INTO memory_fts(memory_fts, rowid, source, heading, content)
|
|
37279
|
+
VALUES ('delete', old.rowid, old.source, old.heading, old.content);
|
|
37280
|
+
END;
|
|
37281
|
+
`);
|
|
37282
|
+
if (this._vecAvailable) {
|
|
37283
|
+
try {
|
|
37284
|
+
db.exec(`
|
|
37285
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS memory_vec USING vec0(
|
|
37286
|
+
embedding FLOAT[${this.config.vectorDimension}]
|
|
37287
|
+
);
|
|
37288
|
+
`);
|
|
37289
|
+
} catch (err) {
|
|
37290
|
+
console.warn("[memory-store] Failed to create memory_vec, disabling vector search:", err);
|
|
37291
|
+
this._vecAvailable = false;
|
|
37292
|
+
}
|
|
37254
37293
|
}
|
|
37294
|
+
} catch (err) {
|
|
37295
|
+
throw new StoreError("schema migration failed", err);
|
|
37255
37296
|
}
|
|
37256
37297
|
}
|
|
37257
37298
|
upsert(chunks, embeddings) {
|
|
37258
37299
|
const insertChunk = this.db.prepare(`
|
|
37259
37300
|
INSERT OR REPLACE INTO memory_chunks
|
|
37260
|
-
(id, source, heading, heading_level, content, line_start, line_end, indexed_at)
|
|
37261
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
37301
|
+
(id, source, source_type, heading, heading_level, content, line_start, line_end, indexed_at, file_mtime_at)
|
|
37302
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
37262
37303
|
`);
|
|
37263
37304
|
let insertVec = null;
|
|
37264
37305
|
if (this._vecAvailable) {
|
|
@@ -37272,15 +37313,17 @@ var MemoryStore = class {
|
|
|
37272
37313
|
const info = insertChunk.run(
|
|
37273
37314
|
chunk.id,
|
|
37274
37315
|
chunk.source,
|
|
37316
|
+
chunk.sourceType,
|
|
37275
37317
|
chunk.heading,
|
|
37276
37318
|
chunk.headingLevel,
|
|
37277
37319
|
chunk.content,
|
|
37278
37320
|
chunk.lineStart,
|
|
37279
37321
|
chunk.lineEnd,
|
|
37280
|
-
Date.now()
|
|
37322
|
+
Date.now(),
|
|
37323
|
+
chunk.fileMtimeAt
|
|
37281
37324
|
);
|
|
37282
37325
|
if (insertVec && embeddings[i] && info.lastInsertRowid) {
|
|
37283
|
-
const rowid =
|
|
37326
|
+
const rowid = typeof info.lastInsertRowid === "bigint" ? info.lastInsertRowid : BigInt(info.lastInsertRowid);
|
|
37284
37327
|
const emb = embeddings[i];
|
|
37285
37328
|
const buf = Buffer.from(emb.buffer, emb.byteOffset, emb.byteLength);
|
|
37286
37329
|
insertVec.run(rowid, buf);
|
|
@@ -37304,6 +37347,20 @@ var MemoryStore = class {
|
|
|
37304
37347
|
const rows = this.db.prepare(`SELECT DISTINCT source FROM memory_chunks`).all();
|
|
37305
37348
|
return rows.map((r) => r.source);
|
|
37306
37349
|
}
|
|
37350
|
+
getRecentSources(options) {
|
|
37351
|
+
const limit = Math.min(Math.max(1, options.limit || 5), 50);
|
|
37352
|
+
const whereClause = options.sourceType ? " WHERE source_type = ?" : "";
|
|
37353
|
+
const params = options.sourceType ? [options.sourceType, limit] : [limit];
|
|
37354
|
+
try {
|
|
37355
|
+
const rows = this.db.prepare(
|
|
37356
|
+
`SELECT source, MAX(file_mtime_at) AS t FROM memory_chunks${whereClause} GROUP BY source ORDER BY t DESC LIMIT ?`
|
|
37357
|
+
).all(...params);
|
|
37358
|
+
return rows.map((row) => ({ source: row.source, fileMtimeAt: row.t }));
|
|
37359
|
+
} catch (err) {
|
|
37360
|
+
console.warn("[memory-store] Recent source lookup failed:", err);
|
|
37361
|
+
return [];
|
|
37362
|
+
}
|
|
37363
|
+
}
|
|
37307
37364
|
deleteBySource(source) {
|
|
37308
37365
|
const rows = this.db.prepare(`SELECT rowid FROM memory_chunks WHERE source = ?`).all(source);
|
|
37309
37366
|
const deleteAll = this.db.transaction(() => {
|
|
@@ -37380,17 +37437,19 @@ var MemoryStore = class {
|
|
|
37380
37437
|
if (ids.length === 0) return [];
|
|
37381
37438
|
const placeholders = ids.map(() => "?").join(", ");
|
|
37382
37439
|
const rows = this.db.prepare(
|
|
37383
|
-
`SELECT id, source, heading, heading_level, content, line_start, line_end
|
|
37440
|
+
`SELECT id, source, source_type, heading, heading_level, content, line_start, line_end, file_mtime_at
|
|
37384
37441
|
FROM memory_chunks WHERE id IN (${placeholders})`
|
|
37385
37442
|
).all(...ids);
|
|
37386
37443
|
return rows.map((r) => ({
|
|
37387
37444
|
id: r.id,
|
|
37388
37445
|
source: r.source,
|
|
37446
|
+
sourceType: r.source_type,
|
|
37389
37447
|
heading: r.heading,
|
|
37390
37448
|
headingLevel: r.heading_level,
|
|
37391
37449
|
content: r.content,
|
|
37392
37450
|
lineStart: r.line_start,
|
|
37393
|
-
lineEnd: r.line_end
|
|
37451
|
+
lineEnd: r.line_end,
|
|
37452
|
+
fileMtimeAt: r.file_mtime_at
|
|
37394
37453
|
}));
|
|
37395
37454
|
}
|
|
37396
37455
|
get vecAvailable() {
|
|
@@ -37407,8 +37466,8 @@ import * as path13 from "node:path";
|
|
|
37407
37466
|
|
|
37408
37467
|
// src/services/digest/constants.ts
|
|
37409
37468
|
import * as path10 from "node:path";
|
|
37410
|
-
var DEFAULT_DIGEST_MODEL_ID = "
|
|
37411
|
-
var DEFAULT_DIGEST_MAX_INPUT_CHARS =
|
|
37469
|
+
var DEFAULT_DIGEST_MODEL_ID = "base" /* BASE */;
|
|
37470
|
+
var DEFAULT_DIGEST_MAX_INPUT_CHARS = 1e4;
|
|
37412
37471
|
var DEFAULT_DIGEST_TIMEOUT_MS = 12e4;
|
|
37413
37472
|
var KIT_DIR = ".agent-kit";
|
|
37414
37473
|
var WIKI_DIR = path10.join(KIT_DIR, "wiki");
|
|
@@ -37418,7 +37477,7 @@ var DIGEST_WORKER_DIR = path10.join(WIKI_DIR, "digest");
|
|
|
37418
37477
|
var DIGEST_LOCKFILE_REL_PATH = path10.join(DIGEST_WORKER_DIR, "digest-worker.lock");
|
|
37419
37478
|
var DIGEST_WORKER_STATUS_REL_PATH = path10.join(DIGEST_WORKER_DIR, "digest-worker.status.json");
|
|
37420
37479
|
var DIGEST_WORKER_LOG_REL_PATH = path10.join(DIGEST_WORKER_DIR, "digest-worker.log");
|
|
37421
|
-
var LLAMA_CONTEXT_SIZE =
|
|
37480
|
+
var LLAMA_CONTEXT_SIZE = 8192;
|
|
37422
37481
|
var LLAMA_MAX_GENERATED_TOKENS = 512;
|
|
37423
37482
|
var LLAMA_TEMPERATURE = 0.1;
|
|
37424
37483
|
|
|
@@ -37451,9 +37510,9 @@ function writeProvisionalDigestFile(outDir, input, markdown) {
|
|
|
37451
37510
|
return markdownPath;
|
|
37452
37511
|
}
|
|
37453
37512
|
function writeConversationDigestSettings(workspaceRoot2, digest) {
|
|
37454
|
-
const current =
|
|
37513
|
+
const current = loadGlobalSettings();
|
|
37455
37514
|
const memory = current.memory ?? {};
|
|
37456
|
-
|
|
37515
|
+
writeGlobalSettings({
|
|
37457
37516
|
memory: {
|
|
37458
37517
|
...memory,
|
|
37459
37518
|
enabled: memory.enabled ?? true,
|
|
@@ -37478,8 +37537,8 @@ var DIGEST_MODEL_REGISTRY = {
|
|
|
37478
37537
|
sourceUrl: "https://huggingface.co/bartowski/Qwen2.5-0.5B-Instruct-GGUF",
|
|
37479
37538
|
enabled: true
|
|
37480
37539
|
},
|
|
37481
|
-
["
|
|
37482
|
-
id: "
|
|
37540
|
+
["base" /* BASE */]: {
|
|
37541
|
+
id: "base" /* BASE */,
|
|
37483
37542
|
ggufUri: "hf:bartowski/Qwen2.5-1.5B-Instruct-GGUF/Qwen2.5-1.5B-Instruct-Q4_K_M.gguf",
|
|
37484
37543
|
approxSizeBytes: 1e9,
|
|
37485
37544
|
license: "Apache-2.0",
|
|
@@ -37556,39 +37615,19 @@ function buildPrompt(input, maxInputChars) {
|
|
|
37556
37615
|
{
|
|
37557
37616
|
role: "system",
|
|
37558
37617
|
content: [
|
|
37559
|
-
"
|
|
37560
|
-
"
|
|
37561
|
-
"
|
|
37562
|
-
""
|
|
37563
|
-
"# RULES",
|
|
37564
|
-
"1. Read the end of the export FIRST to discover the ultimate resolution.",
|
|
37565
|
-
"2. What the user says LAST ALWAYS overrides earlier agreements.",
|
|
37566
|
-
"3. Capture absolute engineering conclusions, never conversational pleasantries.",
|
|
37567
|
-
"4. Return Markdown only. Do not wrap output in code blocks (```markdown ... ```)."
|
|
37618
|
+
"You are a technical summarizer.",
|
|
37619
|
+
"Focus ONLY on the final decisions made at the end of the transcript.",
|
|
37620
|
+
"Never invent or guess details.",
|
|
37621
|
+
"Keep the output concise and strictly factual."
|
|
37568
37622
|
].join("\n")
|
|
37569
37623
|
},
|
|
37570
37624
|
{
|
|
37571
37625
|
role: "user",
|
|
37572
37626
|
content: [
|
|
37573
|
-
"
|
|
37574
|
-
"",
|
|
37575
|
-
"<layout>",
|
|
37576
|
-
"# Digest: " + titleFromSource(input.sourcePath),
|
|
37577
|
-
"- **Ultimate Core Resolution**: [Describe the final working state of the feature and what problem it solves in 1-2 sentences. No conversational filler.]",
|
|
37578
|
-
"- **Architectural Changes**: [List 3-4 high-level engineering decisions made (e.g., shifts in hook timing, data isolation, atomic locks). Focus on systemic changes, NOT individual files.]",
|
|
37579
|
-
"- **Component State**: [Briefly state how the Plugin side and the MCP/CLI side now interact based on the final decision.]",
|
|
37580
|
-
"- **Considered & Rejected**: [List concepts proposed but discarded (e.g., initial hooks location, mocking strategies). Omit if empty.]",
|
|
37581
|
-
"</layout>",
|
|
37582
|
-
"",
|
|
37583
|
-
"# CRITICAL RULES:",
|
|
37584
|
-
"- DO NOT list individual file paths, line numbers, or specific test cases (EXCLUDE lists of files).",
|
|
37585
|
-
"- Focus entirely on the SYSTEM DESIGN and ARCHITECTURE that the next engineer needs to know.",
|
|
37586
|
-
"- Keep output under 300 tokens. Stop immediately after the last valid section.",
|
|
37587
|
-
"",
|
|
37588
|
-
"Source path: " + input.sourcePath,
|
|
37589
|
-
'<conversation_export format="memory-kit">',
|
|
37627
|
+
"Transcript:",
|
|
37590
37628
|
conversationExport,
|
|
37591
|
-
"
|
|
37629
|
+
"",
|
|
37630
|
+
"Task: Write a brief summary paragraph of the final agreed-upon decisions in the transcript above. Then, provide a simple bulleted list of the specific technical changes or outcomes."
|
|
37592
37631
|
].join("\n")
|
|
37593
37632
|
}
|
|
37594
37633
|
];
|
|
@@ -37651,7 +37690,18 @@ async function createLlamaLocalDigestProvider(modelId) {
|
|
|
37651
37690
|
options.timeoutMs,
|
|
37652
37691
|
() => new LlamaLocalDigestProviderError(`Llama provider timed out after ${options.timeoutMs}ms`)
|
|
37653
37692
|
);
|
|
37654
|
-
|
|
37693
|
+
const metadata = `## Digest: ${titleFromSource(input.sourcePath)}
|
|
37694
|
+
|
|
37695
|
+
| Key | Value |
|
|
37696
|
+
| ------ | ----- |
|
|
37697
|
+
| **Source** | ${input.sourcePath} |
|
|
37698
|
+
| **Generated** | ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]} |
|
|
37699
|
+
| **Model** | ${modelId} |
|
|
37700
|
+
`;
|
|
37701
|
+
const sanitized = sanitizeConversationDigestMarkdown(response);
|
|
37702
|
+
return `${metadata}
|
|
37703
|
+
|
|
37704
|
+
${sanitized}`;
|
|
37655
37705
|
} finally {
|
|
37656
37706
|
await context.dispose();
|
|
37657
37707
|
}
|
|
@@ -37685,19 +37735,25 @@ function discoverPendingConversationFiles(workspaceRoot2) {
|
|
|
37685
37735
|
}
|
|
37686
37736
|
});
|
|
37687
37737
|
}
|
|
37688
|
-
async function indexProvisionalDigestFile(workspaceRoot2, markdownPath) {
|
|
37738
|
+
async function indexProvisionalDigestFile(workspaceRoot2, markdownPath, indexer) {
|
|
37739
|
+
let store;
|
|
37689
37740
|
try {
|
|
37690
|
-
|
|
37691
|
-
|
|
37692
|
-
|
|
37693
|
-
|
|
37694
|
-
|
|
37695
|
-
const
|
|
37696
|
-
|
|
37741
|
+
if (indexer) {
|
|
37742
|
+
await indexer.indexFile(markdownPath);
|
|
37743
|
+
return { indexed: true };
|
|
37744
|
+
}
|
|
37745
|
+
const settings = loadGlobalSettings();
|
|
37746
|
+
const config2 = resolveMemoryConfig(settings, workspaceRoot2);
|
|
37747
|
+
if (config2.enabled !== true) return { indexed: false };
|
|
37748
|
+
store = new MemoryStore(path13.join(config2.wikiDir, "index.db"), config2);
|
|
37749
|
+
const embedder = new Embedder(config2.embeddingModel);
|
|
37750
|
+
await embedder.initialize();
|
|
37751
|
+
await new MemoryIndexer(store, embedder, config2).indexFile(markdownPath);
|
|
37697
37752
|
return { indexed: true };
|
|
37698
37753
|
} catch (err) {
|
|
37699
|
-
|
|
37700
|
-
|
|
37754
|
+
return { indexed: false, error: err instanceof Error ? err.message : String(err) };
|
|
37755
|
+
} finally {
|
|
37756
|
+
store?.close();
|
|
37701
37757
|
}
|
|
37702
37758
|
}
|
|
37703
37759
|
async function digestConversationFile(options) {
|
|
@@ -37705,7 +37761,7 @@ async function digestConversationFile(options) {
|
|
|
37705
37761
|
const input = readConversationDigestInput(options.workspaceRoot, options.inputPath);
|
|
37706
37762
|
const existingPath = findExistingProvisionalDigest(outDir, input);
|
|
37707
37763
|
if (existingPath) {
|
|
37708
|
-
const indexResult = await indexProvisionalDigestFile(options.workspaceRoot, existingPath);
|
|
37764
|
+
const indexResult = await indexProvisionalDigestFile(options.workspaceRoot, existingPath, options.indexer);
|
|
37709
37765
|
return {
|
|
37710
37766
|
markdown: existingPath,
|
|
37711
37767
|
status: "provisional",
|
|
@@ -37722,7 +37778,7 @@ async function digestConversationFile(options) {
|
|
|
37722
37778
|
timeoutMs: options.timeoutMs ?? DEFAULT_DIGEST_TIMEOUT_MS
|
|
37723
37779
|
});
|
|
37724
37780
|
const markdownPath = writeProvisionalDigestFile(outDir, input, markdown);
|
|
37725
|
-
const indexResult = await indexProvisionalDigestFile(options.workspaceRoot, markdownPath);
|
|
37781
|
+
const indexResult = await indexProvisionalDigestFile(options.workspaceRoot, markdownPath, options.indexer);
|
|
37726
37782
|
return {
|
|
37727
37783
|
markdown: markdownPath,
|
|
37728
37784
|
status: "provisional",
|
|
@@ -37739,7 +37795,7 @@ async function digestPendingConversations({
|
|
|
37739
37795
|
digestFn = digestConversationFile,
|
|
37740
37796
|
onProgress
|
|
37741
37797
|
}) {
|
|
37742
|
-
const digestConfig = resolveConversationDigestConfig(
|
|
37798
|
+
const digestConfig = resolveConversationDigestConfig(loadGlobalSettings());
|
|
37743
37799
|
if (!digestConfig || digestConfig.enabled === false) {
|
|
37744
37800
|
return { ok: true, initialized: false, action: "noop", reason: "not-initialized" };
|
|
37745
37801
|
}
|
|
@@ -37747,11 +37803,21 @@ async function digestPendingConversations({
|
|
|
37747
37803
|
if (!tryAcquireProcessLock(lockPath)) {
|
|
37748
37804
|
return { ok: true, initialized: true, action: "noop", reason: "locked" };
|
|
37749
37805
|
}
|
|
37806
|
+
let closeIndexer;
|
|
37750
37807
|
try {
|
|
37751
37808
|
const candidates = discoverPendingConversationFiles(workspaceRoot2);
|
|
37752
37809
|
if (candidates.length === 0) {
|
|
37753
37810
|
return { ok: true, initialized: true, action: "noop", reason: "no-pending" };
|
|
37754
37811
|
}
|
|
37812
|
+
let indexer;
|
|
37813
|
+
const memoryConfig = resolveMemoryConfig(loadGlobalSettings(), workspaceRoot2);
|
|
37814
|
+
if (memoryConfig.enabled === true) {
|
|
37815
|
+
const store = new MemoryStore(path13.join(memoryConfig.wikiDir, "index.db"), memoryConfig);
|
|
37816
|
+
const embedder = new Embedder(memoryConfig.embeddingModel);
|
|
37817
|
+
indexer = new MemoryIndexer(store, embedder, memoryConfig);
|
|
37818
|
+
closeIndexer = () => store.close();
|
|
37819
|
+
await embedder.initialize();
|
|
37820
|
+
}
|
|
37755
37821
|
let count = 0;
|
|
37756
37822
|
let skipped = 0;
|
|
37757
37823
|
let errors = 0;
|
|
@@ -37760,7 +37826,8 @@ async function digestPendingConversations({
|
|
|
37760
37826
|
const result = await digestFn({
|
|
37761
37827
|
workspaceRoot: workspaceRoot2,
|
|
37762
37828
|
inputPath: filePath,
|
|
37763
|
-
modelId: digestConfig.modelId
|
|
37829
|
+
modelId: digestConfig.modelId,
|
|
37830
|
+
indexer
|
|
37764
37831
|
});
|
|
37765
37832
|
if (result.skipped) {
|
|
37766
37833
|
skipped++;
|
|
@@ -37777,9 +37844,17 @@ async function digestPendingConversations({
|
|
|
37777
37844
|
return { ok: true, initialized: true, action: "digested", count, skipped, errors };
|
|
37778
37845
|
} catch (err) {
|
|
37779
37846
|
const message = err instanceof Error ? err.message : String(err);
|
|
37847
|
+
console.warn("[digest] Pending conversation digest failed:", err);
|
|
37780
37848
|
return { ok: false, initialized: true, action: "error", error: message };
|
|
37781
37849
|
} finally {
|
|
37782
37850
|
releaseLock(lockPath);
|
|
37851
|
+
if (closeIndexer) {
|
|
37852
|
+
try {
|
|
37853
|
+
closeIndexer();
|
|
37854
|
+
} catch (err) {
|
|
37855
|
+
console.warn("[digest] Failed to close memory indexer store:", err);
|
|
37856
|
+
}
|
|
37857
|
+
}
|
|
37783
37858
|
}
|
|
37784
37859
|
}
|
|
37785
37860
|
async function initializeConversationDigestModel(input) {
|
|
@@ -37821,19 +37896,18 @@ async function initializeConversationDigestModel(input) {
|
|
|
37821
37896
|
function registerMemoryToolHandlers(server2, indexer, store, config2, workspaceRoot2 = process.cwd()) {
|
|
37822
37897
|
server2.tool(
|
|
37823
37898
|
"kit_memory_search",
|
|
37824
|
-
"Search persistent memory for
|
|
37899
|
+
"Search persistent memory for factual or semantic matches (decisions, concepts, entities). Extract concise keywords only, removing stopwords and filler words from the user request before querying. Use kit_memory_recent for temporal or recency questions.",
|
|
37825
37900
|
{
|
|
37826
|
-
query: external_exports.string().min(1).describe("
|
|
37901
|
+
query: external_exports.string().min(1).describe("Keyword-only search query with stopwords removed"),
|
|
37827
37902
|
top_k: external_exports.number().int().positive().optional().describe("Number of results to return")
|
|
37828
37903
|
},
|
|
37829
37904
|
async ({ query, top_k }) => {
|
|
37830
37905
|
try {
|
|
37831
37906
|
const results = await indexer.search(query, top_k ?? config2.topK);
|
|
37907
|
+
const degradedNote = !store.vecAvailable ? "\u26A0\uFE0F Vector search unavailable \u2014 showing keyword-only results.\n\n" : "";
|
|
37832
37908
|
if (results.length === 0) {
|
|
37833
|
-
|
|
37834
|
-
return mcpText(`${degradedNote2}No memories found for query: "${query}"`);
|
|
37909
|
+
return mcpText(`${degradedNote}No memories found for query: "${query}"`);
|
|
37835
37910
|
}
|
|
37836
|
-
const degradedNote = !store.vecAvailable ? "\u26A0\uFE0F Vector search unavailable \u2014 showing keyword-only results.\n\n" : "";
|
|
37837
37911
|
const formatted = results.map((r) => {
|
|
37838
37912
|
const displaySource = r.chunk.source.replace(/^compiled\//, "");
|
|
37839
37913
|
const content = r.contentSource === "fallback" ? `\u26A0\uFE0F Source file unavailable \u2014 showing matched chunk only:
|
|
@@ -37843,8 +37917,36 @@ ${content}`;
|
|
|
37843
37917
|
}).join("\n\n---\n\n");
|
|
37844
37918
|
return mcpText(`${degradedNote}${formatted}`);
|
|
37845
37919
|
} catch (err) {
|
|
37846
|
-
|
|
37847
|
-
|
|
37920
|
+
return mcpText(`kit_memory_search failed: ${formatError2(err)}`);
|
|
37921
|
+
}
|
|
37922
|
+
}
|
|
37923
|
+
);
|
|
37924
|
+
server2.tool(
|
|
37925
|
+
"kit_memory_recent",
|
|
37926
|
+
'Return the N most recently updated memory sources. Optionally filter by source type. Use for temporal questions like "what did we do last session" or "recent".',
|
|
37927
|
+
{
|
|
37928
|
+
n: external_exports.number().int().positive().max(50).optional().describe("How many recent sources to return (default 5)"),
|
|
37929
|
+
source_type: external_exports.enum(SOURCE_TYPES).optional().describe("Optional source type filter")
|
|
37930
|
+
},
|
|
37931
|
+
async ({ n, source_type }) => {
|
|
37932
|
+
try {
|
|
37933
|
+
const rows = store.getRecentSources({ limit: n ?? 5, sourceType: source_type });
|
|
37934
|
+
if (rows.length === 0) return mcpText("No recent sources found.");
|
|
37935
|
+
const blocks = [];
|
|
37936
|
+
for (const row of rows) {
|
|
37937
|
+
try {
|
|
37938
|
+
const content = fs11.readFileSync(path14.join(config2.wikiDir, row.source), "utf8");
|
|
37939
|
+
const displaySource = row.source.replace(/^compiled\//, "");
|
|
37940
|
+
blocks.push(`### ${displaySource}
|
|
37941
|
+
${content}`);
|
|
37942
|
+
} catch (err) {
|
|
37943
|
+
console.warn(`[memory] Skipping unavailable recent source ${row.source}:`, err);
|
|
37944
|
+
}
|
|
37945
|
+
}
|
|
37946
|
+
if (blocks.length === 0) return mcpText("No recent sources found.");
|
|
37947
|
+
return mcpText(blocks.join("\n\n---\n\n"));
|
|
37948
|
+
} catch (err) {
|
|
37949
|
+
return mcpText(`kit_memory_recent failed: ${formatError2(err)}`);
|
|
37848
37950
|
}
|
|
37849
37951
|
}
|
|
37850
37952
|
);
|
|
@@ -37863,8 +37965,10 @@ ${content}`;
|
|
|
37863
37965
|
message: "Saved to wiki/raw \u2014 will be indexed after next /wiki compile"
|
|
37864
37966
|
});
|
|
37865
37967
|
} catch (err) {
|
|
37866
|
-
|
|
37867
|
-
|
|
37968
|
+
return mcpJson({
|
|
37969
|
+
saved: false,
|
|
37970
|
+
error: formatError2(err)
|
|
37971
|
+
});
|
|
37868
37972
|
}
|
|
37869
37973
|
}
|
|
37870
37974
|
);
|
|
@@ -37877,7 +37981,7 @@ ${content}`;
|
|
|
37877
37981
|
},
|
|
37878
37982
|
async ({ model_id, enabled }) => {
|
|
37879
37983
|
try {
|
|
37880
|
-
const existingConfig = resolveConversationDigestConfig(
|
|
37984
|
+
const existingConfig = resolveConversationDigestConfig(loadGlobalSettings());
|
|
37881
37985
|
const result = await initializeConversationDigestModel({
|
|
37882
37986
|
workspaceRoot: workspaceRoot2,
|
|
37883
37987
|
modelId: model_id ?? existingConfig?.modelId ?? DEFAULT_DIGEST_MODEL_ID,
|
|
@@ -37891,15 +37995,15 @@ ${content}`;
|
|
|
37891
37995
|
error: result.error
|
|
37892
37996
|
});
|
|
37893
37997
|
} catch (err) {
|
|
37894
|
-
|
|
37895
|
-
return mcpJson({ initialized: false, error: message });
|
|
37998
|
+
return mcpJson({ initialized: false, error: formatError2(err) });
|
|
37896
37999
|
}
|
|
37897
38000
|
}
|
|
37898
38001
|
);
|
|
37899
38002
|
}
|
|
37900
|
-
function registerMemoryTools(server2,
|
|
37901
|
-
|
|
37902
|
-
|
|
38003
|
+
function registerMemoryTools(server2, workspaceRoot2, overrides) {
|
|
38004
|
+
const settings = overrides?.settings ?? loadGlobalSettings();
|
|
38005
|
+
if (settings.memory?.enabled !== true) return null;
|
|
38006
|
+
const config2 = overrides?.config ?? resolveMemoryConfig(settings, workspaceRoot2);
|
|
37903
38007
|
const store = overrides?.store ?? new MemoryStore(path14.join(config2.wikiDir, "index.db"), config2);
|
|
37904
38008
|
const indexer = overrides?.indexer ?? (() => {
|
|
37905
38009
|
const embedder = new Embedder(config2.embeddingModel);
|
|
@@ -37918,8 +38022,7 @@ registerIntegrationTools(server);
|
|
|
37918
38022
|
registerCoreTools(server);
|
|
37919
38023
|
registerAgentTools(server);
|
|
37920
38024
|
var workspaceRoot = getWorkspaceRoot();
|
|
37921
|
-
var
|
|
37922
|
-
var memoryIndexer = registerMemoryTools(server, settings, workspaceRoot);
|
|
38025
|
+
var memoryIndexer = registerMemoryTools(server, workspaceRoot);
|
|
37923
38026
|
var transport = new StdioServerTransport();
|
|
37924
38027
|
await server.connect(transport);
|
|
37925
38028
|
if (memoryIndexer) {
|