@agentmemory/agentmemory 0.7.9 → 0.8.1
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 +131 -112
- package/dist/cli.mjs +57 -13
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +149 -17
- package/dist/index.mjs.map +1 -1
- package/dist/{src-DNbB7fd7.mjs → src-Df36IFVL.mjs} +150 -18
- package/dist/src-Df36IFVL.mjs.map +1 -0
- package/dist/standalone.mjs +1 -1
- package/dist/standalone.mjs.map +1 -1
- package/dist/viewer/index.html +2888 -0
- package/package.json +2 -2
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/src-DNbB7fd7.mjs.map +0 -1
|
@@ -39,10 +39,16 @@ function loadEnvFile() {
|
|
|
39
39
|
}
|
|
40
40
|
function detectProvider(env) {
|
|
41
41
|
const maxTokens = parseInt(env["MAX_TOKENS"] || "4096", 10);
|
|
42
|
+
if (env["MINIMAX_API_KEY"]) return {
|
|
43
|
+
provider: "minimax",
|
|
44
|
+
model: env["MINIMAX_MODEL"] || "MiniMax-M2.7",
|
|
45
|
+
maxTokens
|
|
46
|
+
};
|
|
42
47
|
if (env["ANTHROPIC_API_KEY"]) return {
|
|
43
48
|
provider: "anthropic",
|
|
44
49
|
model: env["ANTHROPIC_MODEL"] || "claude-sonnet-4-20250514",
|
|
45
|
-
maxTokens
|
|
50
|
+
maxTokens,
|
|
51
|
+
baseURL: env["ANTHROPIC_BASE_URL"]
|
|
46
52
|
};
|
|
47
53
|
if (env["GEMINI_API_KEY"]) return {
|
|
48
54
|
provider: "gemini",
|
|
@@ -156,7 +162,8 @@ const VALID_PROVIDERS = new Set([
|
|
|
156
162
|
"anthropic",
|
|
157
163
|
"gemini",
|
|
158
164
|
"openrouter",
|
|
159
|
-
"agent-sdk"
|
|
165
|
+
"agent-sdk",
|
|
166
|
+
"minimax"
|
|
160
167
|
]);
|
|
161
168
|
function loadFallbackConfig() {
|
|
162
169
|
return { providers: (getMergedEnv()["FALLBACK_PROVIDERS"] || "").split(",").map((p) => p.trim()).filter((p) => Boolean(p) && VALID_PROVIDERS.has(p)) };
|
|
@@ -195,8 +202,11 @@ var AnthropicProvider = class {
|
|
|
195
202
|
client;
|
|
196
203
|
model;
|
|
197
204
|
maxTokens;
|
|
198
|
-
constructor(apiKey, model, maxTokens) {
|
|
199
|
-
this.client = new Anthropic({
|
|
205
|
+
constructor(apiKey, model, maxTokens, baseURL) {
|
|
206
|
+
this.client = new Anthropic({
|
|
207
|
+
apiKey,
|
|
208
|
+
...baseURL ? { baseURL } : {}
|
|
209
|
+
});
|
|
200
210
|
this.model = model;
|
|
201
211
|
this.maxTokens = maxTokens;
|
|
202
212
|
}
|
|
@@ -219,6 +229,67 @@ var AnthropicProvider = class {
|
|
|
219
229
|
}
|
|
220
230
|
};
|
|
221
231
|
|
|
232
|
+
//#endregion
|
|
233
|
+
//#region src/providers/minimax.ts
|
|
234
|
+
/**
|
|
235
|
+
* MiniMax provider using raw fetch to call MiniMax's Anthropic-compatible API.
|
|
236
|
+
*
|
|
237
|
+
* The Anthropic SDK automatically injects `x-stainless-*` headers that MiniMax
|
|
238
|
+
* rejects with 403. This provider bypasses the SDK and calls the API directly.
|
|
239
|
+
*
|
|
240
|
+
* Required env vars:
|
|
241
|
+
* MINIMAX_API_KEY — your MiniMax API key
|
|
242
|
+
* MINIMAX_MODEL — model name (default: MiniMax-M2.7)
|
|
243
|
+
* MAX_TOKENS — max output tokens (default: 800; MiniMax-M2.7 needs ≤800)
|
|
244
|
+
*
|
|
245
|
+
* Optional:
|
|
246
|
+
* MINIMAX_BASE_URL — base URL without path (default: https://api.minimaxi.com/anthropic)
|
|
247
|
+
*/
|
|
248
|
+
var MinimaxProvider = class {
|
|
249
|
+
name = "minimax";
|
|
250
|
+
apiKey;
|
|
251
|
+
model;
|
|
252
|
+
maxTokens;
|
|
253
|
+
baseUrl;
|
|
254
|
+
constructor(apiKey, model, maxTokens) {
|
|
255
|
+
this.apiKey = apiKey;
|
|
256
|
+
this.model = model;
|
|
257
|
+
this.maxTokens = maxTokens;
|
|
258
|
+
this.baseUrl = process.env["MINIMAX_BASE_URL"] || "https://api.minimaxi.com/anthropic";
|
|
259
|
+
}
|
|
260
|
+
async compress(systemPrompt, userPrompt) {
|
|
261
|
+
return this.call(systemPrompt, userPrompt);
|
|
262
|
+
}
|
|
263
|
+
async summarize(systemPrompt, userPrompt) {
|
|
264
|
+
return this.call(systemPrompt, userPrompt);
|
|
265
|
+
}
|
|
266
|
+
async call(systemPrompt, userPrompt) {
|
|
267
|
+
const url = `${this.baseUrl}/v1/messages`;
|
|
268
|
+
const response = await fetch(url, {
|
|
269
|
+
method: "POST",
|
|
270
|
+
headers: {
|
|
271
|
+
"Content-Type": "application/json",
|
|
272
|
+
"x-api-key": this.apiKey,
|
|
273
|
+
"anthropic-version": "2023-06-01"
|
|
274
|
+
},
|
|
275
|
+
body: JSON.stringify({
|
|
276
|
+
model: this.model,
|
|
277
|
+
max_tokens: this.maxTokens,
|
|
278
|
+
system: systemPrompt,
|
|
279
|
+
messages: [{
|
|
280
|
+
role: "user",
|
|
281
|
+
content: userPrompt
|
|
282
|
+
}]
|
|
283
|
+
})
|
|
284
|
+
});
|
|
285
|
+
if (!response.ok) {
|
|
286
|
+
const text = await response.text();
|
|
287
|
+
throw new Error(`MiniMax API error ${response.status}: ${text}`);
|
|
288
|
+
}
|
|
289
|
+
return ((await response.json()).content?.find((b) => b.type === "text"))?.text ?? "";
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
|
|
222
293
|
//#endregion
|
|
223
294
|
//#region src/providers/openrouter.ts
|
|
224
295
|
var OpenRouterProvider = class {
|
|
@@ -646,7 +717,8 @@ function createFallbackProvider(config, fallbackConfig) {
|
|
|
646
717
|
}
|
|
647
718
|
function createBaseProvider(config) {
|
|
648
719
|
switch (config.provider) {
|
|
649
|
-
case "
|
|
720
|
+
case "minimax": return new MinimaxProvider(requireEnvVar("MINIMAX_API_KEY"), config.model, config.maxTokens);
|
|
721
|
+
case "anthropic": return new AnthropicProvider(requireEnvVar("ANTHROPIC_API_KEY"), config.model, config.maxTokens, config.baseURL);
|
|
650
722
|
case "gemini": return new OpenRouterProvider(requireEnvVar("GEMINI_API_KEY"), config.model, config.maxTokens, "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions");
|
|
651
723
|
case "openrouter": return new OpenRouterProvider(requireEnvVar("OPENROUTER_API_KEY"), config.model, config.maxTokens, "https://openrouter.ai/api/v1/chat/completions");
|
|
652
724
|
default: return new AgentSDKProvider();
|
|
@@ -2122,23 +2194,56 @@ function registerSearchFunction(sdk, kv) {
|
|
|
2122
2194
|
}, async (data) => {
|
|
2123
2195
|
const ctx = getContext();
|
|
2124
2196
|
const idx = getSearchIndex();
|
|
2197
|
+
if (typeof data?.query !== "string" || !data.query.trim()) throw new Error("mem::search: query must be a non-empty string");
|
|
2198
|
+
const query = data.query.trim();
|
|
2199
|
+
const MAX_LIMIT = 100;
|
|
2200
|
+
let effectiveLimit = 20;
|
|
2201
|
+
if (data.limit !== void 0) {
|
|
2202
|
+
if (!Number.isInteger(data.limit) || data.limit < 1) throw new Error("mem::search: limit must be a positive integer");
|
|
2203
|
+
effectiveLimit = Math.min(data.limit, MAX_LIMIT);
|
|
2204
|
+
}
|
|
2205
|
+
const projectFilter = typeof data.project === "string" && data.project.length > 0 ? data.project : void 0;
|
|
2206
|
+
const cwdFilter = typeof data.cwd === "string" && data.cwd.length > 0 ? data.cwd : void 0;
|
|
2125
2207
|
if (idx.size === 0) {
|
|
2126
2208
|
const count = await rebuildIndex(kv);
|
|
2127
2209
|
ctx.logger.info("Search index rebuilt", { entries: count });
|
|
2128
2210
|
}
|
|
2129
|
-
const
|
|
2130
|
-
const
|
|
2211
|
+
const filtering = !!(projectFilter || cwdFilter);
|
|
2212
|
+
const fetchLimit = filtering ? Math.max(effectiveLimit * 10, 100) : effectiveLimit;
|
|
2213
|
+
const results = idx.search(query, fetchLimit);
|
|
2214
|
+
const sessionCache = /* @__PURE__ */ new Map();
|
|
2215
|
+
const loadSession = async (sessionId) => {
|
|
2216
|
+
if (sessionCache.has(sessionId)) return sessionCache.get(sessionId);
|
|
2217
|
+
const s = await kv.get(KV.sessions, sessionId);
|
|
2218
|
+
sessionCache.set(sessionId, s ?? null);
|
|
2219
|
+
return s ?? null;
|
|
2220
|
+
};
|
|
2221
|
+
const candidates = [];
|
|
2131
2222
|
for (const r of results) {
|
|
2132
|
-
|
|
2223
|
+
if (candidates.length >= effectiveLimit) break;
|
|
2224
|
+
if (filtering) {
|
|
2225
|
+
const s = await loadSession(r.sessionId);
|
|
2226
|
+
if (!s) continue;
|
|
2227
|
+
if (projectFilter && s.project !== projectFilter) continue;
|
|
2228
|
+
if (cwdFilter && s.cwd !== cwdFilter) continue;
|
|
2229
|
+
}
|
|
2230
|
+
candidates.push(r);
|
|
2231
|
+
}
|
|
2232
|
+
const obsResults = await Promise.all(candidates.map((r) => kv.get(KV.observations(r.sessionId), r.obsId)));
|
|
2233
|
+
const enriched = [];
|
|
2234
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
2235
|
+
const obs = obsResults[i];
|
|
2133
2236
|
if (obs) enriched.push({
|
|
2134
2237
|
observation: obs,
|
|
2135
|
-
score:
|
|
2136
|
-
sessionId:
|
|
2238
|
+
score: candidates[i].score,
|
|
2239
|
+
sessionId: candidates[i].sessionId
|
|
2137
2240
|
});
|
|
2138
2241
|
}
|
|
2139
2242
|
ctx.logger.info("Search completed", {
|
|
2140
|
-
query
|
|
2141
|
-
results: enriched.length
|
|
2243
|
+
query,
|
|
2244
|
+
results: enriched.length,
|
|
2245
|
+
hasProjectFilter: !!projectFilter,
|
|
2246
|
+
hasCwdFilter: !!cwdFilter
|
|
2142
2247
|
});
|
|
2143
2248
|
return { results: enriched };
|
|
2144
2249
|
});
|
|
@@ -3804,7 +3909,7 @@ function registerAutoForgetFunction(sdk, kv) {
|
|
|
3804
3909
|
|
|
3805
3910
|
//#endregion
|
|
3806
3911
|
//#region src/version.ts
|
|
3807
|
-
const VERSION = "0.
|
|
3912
|
+
const VERSION = "0.8.1";
|
|
3808
3913
|
|
|
3809
3914
|
//#endregion
|
|
3810
3915
|
//#region src/functions/export-import.ts
|
|
@@ -3909,7 +4014,9 @@ function registerExportImportFunction(sdk, kv) {
|
|
|
3909
4014
|
"0.7.5",
|
|
3910
4015
|
"0.7.6",
|
|
3911
4016
|
"0.7.7",
|
|
3912
|
-
"0.7.9"
|
|
4017
|
+
"0.7.9",
|
|
4018
|
+
"0.8.0",
|
|
4019
|
+
"0.8.1"
|
|
3913
4020
|
]).has(importData.version)) return {
|
|
3914
4021
|
success: false,
|
|
3915
4022
|
error: `Unsupported export version: ${importData.version}`
|
|
@@ -10032,9 +10139,32 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
|
|
|
10032
10139
|
sdk.registerFunction({ id: "api::search" }, async (req) => {
|
|
10033
10140
|
const authErr = checkAuth$1(req, secret);
|
|
10034
10141
|
if (authErr) return authErr;
|
|
10142
|
+
const body = req.body ?? {};
|
|
10143
|
+
if (typeof body.query !== "string" || !body.query.trim()) return {
|
|
10144
|
+
status_code: 400,
|
|
10145
|
+
body: { error: "query is required and must be a non-empty string" }
|
|
10146
|
+
};
|
|
10147
|
+
if (body.limit !== void 0 && (!Number.isInteger(body.limit) || body.limit < 1)) return {
|
|
10148
|
+
status_code: 400,
|
|
10149
|
+
body: { error: "limit must be a positive integer" }
|
|
10150
|
+
};
|
|
10151
|
+
if (body.project !== void 0 && typeof body.project !== "string") return {
|
|
10152
|
+
status_code: 400,
|
|
10153
|
+
body: { error: "project must be a string" }
|
|
10154
|
+
};
|
|
10155
|
+
if (body.cwd !== void 0 && typeof body.cwd !== "string") return {
|
|
10156
|
+
status_code: 400,
|
|
10157
|
+
body: { error: "cwd must be a string" }
|
|
10158
|
+
};
|
|
10159
|
+
const payload = {
|
|
10160
|
+
query: body.query.trim(),
|
|
10161
|
+
limit: body.limit,
|
|
10162
|
+
project: body.project,
|
|
10163
|
+
cwd: body.cwd
|
|
10164
|
+
};
|
|
10035
10165
|
return {
|
|
10036
10166
|
status_code: 200,
|
|
10037
|
-
body: await sdk.trigger("mem::search",
|
|
10167
|
+
body: await sdk.trigger("mem::search", payload)
|
|
10038
10168
|
};
|
|
10039
10169
|
});
|
|
10040
10170
|
sdk.registerTrigger({
|
|
@@ -14335,9 +14465,11 @@ function startViewerServer(port, _kv, _sdk, secret, restPort) {
|
|
|
14335
14465
|
if (method === "GET" && (pathname === "/" || pathname === "/viewer" || pathname === "/agentmemory/viewer")) {
|
|
14336
14466
|
const base = dirname(fileURLToPath(import.meta.url));
|
|
14337
14467
|
const candidates = [
|
|
14338
|
-
join(base, "
|
|
14468
|
+
join(base, "index.html"),
|
|
14469
|
+
join(base, "viewer", "index.html"),
|
|
14339
14470
|
join(base, "..", "viewer", "index.html"),
|
|
14340
|
-
join(base, "viewer", "index.html")
|
|
14471
|
+
join(base, "..", "src", "viewer", "index.html"),
|
|
14472
|
+
join(base, "..", "dist", "viewer", "index.html")
|
|
14341
14473
|
];
|
|
14342
14474
|
for (const p of candidates) try {
|
|
14343
14475
|
const html = readFileSync(p, "utf-8");
|
|
@@ -14727,4 +14859,4 @@ main().catch((err) => {
|
|
|
14727
14859
|
|
|
14728
14860
|
//#endregion
|
|
14729
14861
|
export { };
|
|
14730
|
-
//# sourceMappingURL=src-
|
|
14862
|
+
//# sourceMappingURL=src-Df36IFVL.mjs.map
|