@prom.codes/memory-mcp 0.11.1 → 0.11.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/dist/bin.js +68 -16
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -676,6 +676,7 @@ var DEFAULT_BATCH2 = 128;
|
|
|
676
676
|
var DEFAULT_BATCH_CHARS = 4e5;
|
|
677
677
|
var DEFAULT_RETRIES2 = 4;
|
|
678
678
|
var DEFAULT_BACKOFF2 = 250;
|
|
679
|
+
var DEFAULT_TIMEOUT_MS2 = 15e3;
|
|
679
680
|
function sleep2(ms, signal) {
|
|
680
681
|
return new Promise((resolve3, reject) => {
|
|
681
682
|
if (signal?.aborted === true) {
|
|
@@ -707,6 +708,7 @@ var PrometheusEmbeddingProvider = class {
|
|
|
707
708
|
#maxBatchChars;
|
|
708
709
|
#maxRetries;
|
|
709
710
|
#retryBaseMs;
|
|
711
|
+
#timeoutMs;
|
|
710
712
|
#fetch;
|
|
711
713
|
#identity = null;
|
|
712
714
|
#identityPromise = null;
|
|
@@ -721,8 +723,12 @@ var PrometheusEmbeddingProvider = class {
|
|
|
721
723
|
this.#url = `${(opts.baseUrl ?? DEFAULT_BASE).replace(/\/+$/, "")}/embed`;
|
|
722
724
|
this.#batchSize = opts.batchSize ?? DEFAULT_BATCH2;
|
|
723
725
|
this.#maxBatchChars = opts.maxBatchChars ?? DEFAULT_BATCH_CHARS;
|
|
726
|
+
if (opts.timeoutMs !== void 0 && (!Number.isInteger(opts.timeoutMs) || opts.timeoutMs < 0)) {
|
|
727
|
+
throw new Error(`PrometheusEmbeddingProvider: timeoutMs must be a non-negative integer (0 disables), got ${opts.timeoutMs}`);
|
|
728
|
+
}
|
|
724
729
|
this.#maxRetries = opts.maxRetries ?? DEFAULT_RETRIES2;
|
|
725
730
|
this.#retryBaseMs = opts.retryBaseMs ?? DEFAULT_BACKOFF2;
|
|
731
|
+
this.#timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
|
|
726
732
|
this.#fetch = opts.fetch ?? fetch;
|
|
727
733
|
}
|
|
728
734
|
/**
|
|
@@ -792,8 +798,6 @@ var PrometheusEmbeddingProvider = class {
|
|
|
792
798
|
method: "GET",
|
|
793
799
|
headers: { authorization: `Bearer ${this.#apiKey}` }
|
|
794
800
|
};
|
|
795
|
-
if (signal !== void 0)
|
|
796
|
-
init.signal = signal;
|
|
797
801
|
const payload = await this.#requestJson(init, signal);
|
|
798
802
|
if (payload?.ok !== true || typeof payload.fingerprint !== "string" || payload.fingerprint === "" || !Number.isInteger(payload.dimension) || payload.dimension <= 0) {
|
|
799
803
|
throw nonRetryable2("prometheus-embed: malformed identity response");
|
|
@@ -827,8 +831,6 @@ var PrometheusEmbeddingProvider = class {
|
|
|
827
831
|
},
|
|
828
832
|
body: JSON.stringify({ input: batch, inputType })
|
|
829
833
|
};
|
|
830
|
-
if (signal !== void 0)
|
|
831
|
-
init.signal = signal;
|
|
832
834
|
const payload = await this.#requestJson(init, signal);
|
|
833
835
|
if (payload?.ok !== true || !Array.isArray(payload.embeddings)) {
|
|
834
836
|
throw nonRetryable2("prometheus-embed: malformed embed response");
|
|
@@ -864,8 +866,25 @@ var PrometheusEmbeddingProvider = class {
|
|
|
864
866
|
let attempt = 0;
|
|
865
867
|
let lastError = null;
|
|
866
868
|
while (attempt <= this.#maxRetries) {
|
|
869
|
+
const controller = new AbortController();
|
|
870
|
+
let timedOut = false;
|
|
871
|
+
let timer;
|
|
872
|
+
if (this.#timeoutMs > 0) {
|
|
873
|
+
timer = setTimeout(() => {
|
|
874
|
+
timedOut = true;
|
|
875
|
+
controller.abort();
|
|
876
|
+
}, this.#timeoutMs);
|
|
877
|
+
timer.unref?.();
|
|
878
|
+
}
|
|
879
|
+
const onParentAbort = () => controller.abort();
|
|
880
|
+
if (signal !== void 0) {
|
|
881
|
+
if (signal.aborted)
|
|
882
|
+
controller.abort();
|
|
883
|
+
else
|
|
884
|
+
signal.addEventListener("abort", onParentAbort, { once: true });
|
|
885
|
+
}
|
|
867
886
|
try {
|
|
868
|
-
const res = await this.#fetch(this.#url, init);
|
|
887
|
+
const res = await this.#fetch(this.#url, { ...init, signal: controller.signal });
|
|
869
888
|
if (res.status >= 500 && res.status < 600) {
|
|
870
889
|
lastError = new Error(`prometheus-embed: HTTP ${res.status}`);
|
|
871
890
|
attempt += 1;
|
|
@@ -881,15 +900,21 @@ var PrometheusEmbeddingProvider = class {
|
|
|
881
900
|
}
|
|
882
901
|
return await res.json();
|
|
883
902
|
} catch (err) {
|
|
884
|
-
if (err?.name === "AbortError")
|
|
903
|
+
if (err?.name === "AbortError" && !timedOut)
|
|
885
904
|
throw err;
|
|
886
905
|
if (err?.nonRetryable === true)
|
|
887
906
|
throw err;
|
|
907
|
+
const retryErr = timedOut ? new Error(`prometheus-embed: request timed out after ${this.#timeoutMs}ms`) : err;
|
|
888
908
|
if (attempt >= this.#maxRetries)
|
|
889
|
-
throw
|
|
890
|
-
lastError =
|
|
909
|
+
throw retryErr;
|
|
910
|
+
lastError = retryErr;
|
|
891
911
|
attempt += 1;
|
|
892
912
|
await sleep2(this.#retryBaseMs * 2 ** (attempt - 1), signal);
|
|
913
|
+
} finally {
|
|
914
|
+
if (timer !== void 0)
|
|
915
|
+
clearTimeout(timer);
|
|
916
|
+
if (signal !== void 0)
|
|
917
|
+
signal.removeEventListener("abort", onParentAbort);
|
|
893
918
|
}
|
|
894
919
|
}
|
|
895
920
|
throw lastError instanceof Error ? lastError : new Error(`prometheus-embed: exhausted ${this.#maxRetries} retries`);
|
|
@@ -1076,6 +1101,7 @@ var DEFAULT_BATCH4 = 100;
|
|
|
1076
1101
|
var DEFAULT_BATCH_CHARS2 = 4e5;
|
|
1077
1102
|
var DEFAULT_RETRIES4 = 4;
|
|
1078
1103
|
var DEFAULT_BACKOFF4 = 250;
|
|
1104
|
+
var DEFAULT_TIMEOUT_MS3 = 15e3;
|
|
1079
1105
|
function sleep4(ms, signal) {
|
|
1080
1106
|
return new Promise((resolve3, reject) => {
|
|
1081
1107
|
if (signal?.aborted === true) {
|
|
@@ -1108,6 +1134,7 @@ var PrometheusRerankProvider = class {
|
|
|
1108
1134
|
#maxBatchChars;
|
|
1109
1135
|
#maxRetries;
|
|
1110
1136
|
#retryBaseMs;
|
|
1137
|
+
#timeoutMs;
|
|
1111
1138
|
#fetch;
|
|
1112
1139
|
#creditsUsed = 0;
|
|
1113
1140
|
constructor(opts) {
|
|
@@ -1124,8 +1151,12 @@ var PrometheusRerankProvider = class {
|
|
|
1124
1151
|
this.#url = `${(opts.baseUrl ?? DEFAULT_BASE2).replace(/\/+$/, "")}/rerank`;
|
|
1125
1152
|
this.#batchSize = opts.batchSize ?? DEFAULT_BATCH4;
|
|
1126
1153
|
this.#maxBatchChars = opts.maxBatchChars ?? DEFAULT_BATCH_CHARS2;
|
|
1154
|
+
if (opts.timeoutMs !== void 0 && (!Number.isInteger(opts.timeoutMs) || opts.timeoutMs < 0)) {
|
|
1155
|
+
throw new Error(`PrometheusRerankProvider: timeoutMs must be a non-negative integer (0 disables), got ${opts.timeoutMs}`);
|
|
1156
|
+
}
|
|
1127
1157
|
this.#maxRetries = opts.maxRetries ?? DEFAULT_RETRIES4;
|
|
1128
1158
|
this.#retryBaseMs = opts.retryBaseMs ?? DEFAULT_BACKOFF4;
|
|
1159
|
+
this.#timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS3;
|
|
1129
1160
|
this.#fetch = opts.fetch ?? fetch;
|
|
1130
1161
|
}
|
|
1131
1162
|
/** Cumulative credits charged across all rerank calls of this instance. */
|
|
@@ -1184,8 +1215,6 @@ var PrometheusRerankProvider = class {
|
|
|
1184
1215
|
},
|
|
1185
1216
|
body: JSON.stringify({ query, documents: batch.map((c) => c.text) })
|
|
1186
1217
|
};
|
|
1187
|
-
if (signal !== void 0)
|
|
1188
|
-
init.signal = signal;
|
|
1189
1218
|
const payload = await this.#requestJson(init, signal);
|
|
1190
1219
|
if (payload?.ok !== true || !Array.isArray(payload.results)) {
|
|
1191
1220
|
throw nonRetryable4("prometheus-rerank: malformed rerank response");
|
|
@@ -1217,8 +1246,25 @@ var PrometheusRerankProvider = class {
|
|
|
1217
1246
|
let attempt = 0;
|
|
1218
1247
|
let lastError = null;
|
|
1219
1248
|
while (attempt <= this.#maxRetries) {
|
|
1249
|
+
const controller = new AbortController();
|
|
1250
|
+
let timedOut = false;
|
|
1251
|
+
let timer;
|
|
1252
|
+
if (this.#timeoutMs > 0) {
|
|
1253
|
+
timer = setTimeout(() => {
|
|
1254
|
+
timedOut = true;
|
|
1255
|
+
controller.abort();
|
|
1256
|
+
}, this.#timeoutMs);
|
|
1257
|
+
timer.unref?.();
|
|
1258
|
+
}
|
|
1259
|
+
const onParentAbort = () => controller.abort();
|
|
1260
|
+
if (signal !== void 0) {
|
|
1261
|
+
if (signal.aborted)
|
|
1262
|
+
controller.abort();
|
|
1263
|
+
else
|
|
1264
|
+
signal.addEventListener("abort", onParentAbort, { once: true });
|
|
1265
|
+
}
|
|
1220
1266
|
try {
|
|
1221
|
-
const res = await this.#fetch(this.#url, init);
|
|
1267
|
+
const res = await this.#fetch(this.#url, { ...init, signal: controller.signal });
|
|
1222
1268
|
if (res.status >= 500 && res.status < 600) {
|
|
1223
1269
|
lastError = new Error(`prometheus-rerank: HTTP ${res.status}`);
|
|
1224
1270
|
attempt += 1;
|
|
@@ -1234,15 +1280,21 @@ var PrometheusRerankProvider = class {
|
|
|
1234
1280
|
}
|
|
1235
1281
|
return await res.json();
|
|
1236
1282
|
} catch (err) {
|
|
1237
|
-
if (err?.name === "AbortError")
|
|
1283
|
+
if (err?.name === "AbortError" && !timedOut)
|
|
1238
1284
|
throw err;
|
|
1239
1285
|
if (err?.nonRetryable === true)
|
|
1240
1286
|
throw err;
|
|
1287
|
+
const retryErr = timedOut ? new Error(`prometheus-rerank: request timed out after ${this.#timeoutMs}ms`) : err;
|
|
1241
1288
|
if (attempt >= this.#maxRetries)
|
|
1242
|
-
throw
|
|
1243
|
-
lastError =
|
|
1289
|
+
throw retryErr;
|
|
1290
|
+
lastError = retryErr;
|
|
1244
1291
|
attempt += 1;
|
|
1245
1292
|
await sleep4(this.#retryBaseMs * 2 ** (attempt - 1), signal);
|
|
1293
|
+
} finally {
|
|
1294
|
+
if (timer !== void 0)
|
|
1295
|
+
clearTimeout(timer);
|
|
1296
|
+
if (signal !== void 0)
|
|
1297
|
+
signal.removeEventListener("abort", onParentAbort);
|
|
1246
1298
|
}
|
|
1247
1299
|
}
|
|
1248
1300
|
throw lastError instanceof Error ? lastError : new Error(`prometheus-rerank: exhausted ${this.#maxRetries} retries`);
|
|
@@ -3371,7 +3423,7 @@ ${f.value}`);
|
|
|
3371
3423
|
embeddingsError = err instanceof Error ? err.message : String(err);
|
|
3372
3424
|
}
|
|
3373
3425
|
}
|
|
3374
|
-
const update = await buildUpdateStatus("@prom.codes/memory-mcp", "0.11.
|
|
3426
|
+
const update = await buildUpdateStatus("@prom.codes/memory-mcp", "0.11.3", { isDevBuild: false });
|
|
3375
3427
|
const summary = deps.rootIsHomeOrFsRoot ? `Memory at ${dbPath}: ${stats.total} records, but the workspace resolved to ${workspaceRoot} (home/root) \u2014 open a project folder so memories scope and mirror correctly.` : `Memory at ${dbPath}: ${stats.total} records for project "${projectName}".${update.updateAvailable === true ? ` Update available: ${update.current} \u2192 ${update.latest} (ask me to run update via the context server's update_servers tool).` : ""}`;
|
|
3376
3428
|
return textResult({
|
|
3377
3429
|
installed: true,
|
|
@@ -3407,7 +3459,7 @@ ${f.value}`);
|
|
|
3407
3459
|
// dist/server.js
|
|
3408
3460
|
var SERVER_IDENTITY = {
|
|
3409
3461
|
name: "prometheus-memory-mcp",
|
|
3410
|
-
version: "0.11.
|
|
3462
|
+
version: "0.11.3",
|
|
3411
3463
|
title: "prom.codes Memory"
|
|
3412
3464
|
};
|
|
3413
3465
|
var SERVER_INSTRUCTIONS = "Persistent agent memory for this workspace \u2014 USE IT PROACTIVELY; the user will not tell you to. Protocol:\n1. ONE-TIME: if this workspace has no Prometheus memory rule yet, call memory_setup now (idempotent) so the protocol is installed into the runtime rule files and survives future sessions. (The server also auto-installs it on startup when a project rule file already exists \u2014 memory_setup covers the rest.)\n2. SESSION START: before any non-trivial task, call memory_read to recall facts, decisions and procedures from earlier sessions.\n3. DURING WORK: when the user states a durable preference, decision, correction or project fact, store it with memory_write (semantic for facts, procedural for how-tos) \u2014 without being asked.\n4. LOOK-UP: use memory_search for keyword recall when memory_read is not specific enough.\n5. SESSION END: consolidate what was learned with memory_capture.\nCall memory_status anytime to check what is stored and whether the rule is installed. Never store secrets, API keys or credentials \u2014 such writes are rejected.";
|