memorix 1.8.1 → 1.8.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/CHANGELOG.md +36 -0
- package/dist/cli/index.js +577 -58
- package/dist/index.js +832 -321
- package/dist/maintenance-runner.js +31 -25
- package/dist/media-audio-runner.js +31 -25
- package/dist/media-video-runner.js +31 -25
- package/dist/memcode-runtime/CHANGELOG.md +36 -0
- package/dist/sdk.js +585 -315
- package/dist/vector-backfill-runner.js +31 -25
- package/docs/1.2.0-PROVIDER-QUALITY.md +15 -6
- package/docs/1.3.3-MULTIMODAL-MEDIA-AND-MCP-COMPAT.md +7 -6
- package/docs/1.8.0-RELEASE-CANDIDATE-SPEC.md +13 -8
- package/docs/API_REFERENCE.md +14 -11
- package/docs/CONFIGURATION.md +2 -2
- package/docs/DEVELOPMENT.md +3 -2
- package/docs/README.md +13 -7
- package/package.json +2 -1
- package/plugins/antigravity/memorix/plugin.json +2 -1
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/hermes/memorix/plugin.yaml +1 -1
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/package.json +1 -1
- package/server.json +3 -3
- package/src/cli/commands/serve-http.ts +10 -2
- package/src/cli/commands/serve.ts +26 -7
- package/src/codegraph/external-provider.ts +299 -19
- package/src/config/dotenv-loader.ts +9 -4
- package/src/config.ts +16 -16
- package/src/dashboard/maintenance.ts +4 -1
- package/src/llm/provider.ts +17 -4
- package/src/server/mcp-compat.ts +63 -0
- package/src/server/mcp-diagnostics.ts +13 -4
- package/src/server/mcp-discovery.ts +61 -0
- package/src/server/stdio-startup-gate.ts +263 -0
- package/src/server.ts +4 -4
|
@@ -1350,8 +1350,10 @@ function loadEnvFile(filePath) {
|
|
|
1350
1350
|
loadedEnvFiles.push(filePath);
|
|
1351
1351
|
}
|
|
1352
1352
|
function loadDotenv(projectRoot, options = {}) {
|
|
1353
|
-
|
|
1354
|
-
|
|
1353
|
+
const userHomeDir = options.userHomeDir ?? homedir();
|
|
1354
|
+
const normalizedProjectRoot = projectRoot ?? null;
|
|
1355
|
+
if (dotenvLoaded && dotenvProjectRoot === normalizedProjectRoot && dotenvHomeDir === userHomeDir) return;
|
|
1356
|
+
if (dotenvLoaded && (dotenvProjectRoot !== normalizedProjectRoot || dotenvHomeDir !== userHomeDir)) {
|
|
1355
1357
|
resetDotenv();
|
|
1356
1358
|
}
|
|
1357
1359
|
loadedEnvFiles.length = 0;
|
|
@@ -1360,9 +1362,10 @@ function loadDotenv(projectRoot, options = {}) {
|
|
|
1360
1362
|
if (projectRoot) {
|
|
1361
1363
|
loadEnvFile(getProjectDotenvPath(projectRoot));
|
|
1362
1364
|
}
|
|
1363
|
-
loadEnvFile(getGlobalDotenvPath(
|
|
1365
|
+
loadEnvFile(getGlobalDotenvPath(userHomeDir));
|
|
1364
1366
|
dotenvLoaded = true;
|
|
1365
|
-
dotenvProjectRoot =
|
|
1367
|
+
dotenvProjectRoot = normalizedProjectRoot;
|
|
1368
|
+
dotenvHomeDir = userHomeDir;
|
|
1366
1369
|
}
|
|
1367
1370
|
function resetDotenv() {
|
|
1368
1371
|
for (const key of injectedKeys) {
|
|
@@ -1371,13 +1374,14 @@ function resetDotenv() {
|
|
|
1371
1374
|
injectedKeys.clear();
|
|
1372
1375
|
dotenvLoaded = false;
|
|
1373
1376
|
dotenvProjectRoot = null;
|
|
1377
|
+
dotenvHomeDir = null;
|
|
1374
1378
|
loadedEnvFiles.length = 0;
|
|
1375
1379
|
loadedEnvKeys.clear();
|
|
1376
1380
|
}
|
|
1377
1381
|
function getLoadedEnvFiles() {
|
|
1378
1382
|
return loadedEnvFiles;
|
|
1379
1383
|
}
|
|
1380
|
-
var dotenvLoaded, dotenvProjectRoot, loadedEnvFiles, loadedEnvKeys, loadedEnvValues, injectedKeys;
|
|
1384
|
+
var dotenvLoaded, dotenvProjectRoot, dotenvHomeDir, loadedEnvFiles, loadedEnvKeys, loadedEnvValues, injectedKeys;
|
|
1381
1385
|
var init_dotenv_loader = __esm({
|
|
1382
1386
|
"src/config/dotenv-loader.ts"() {
|
|
1383
1387
|
"use strict";
|
|
@@ -1385,6 +1389,7 @@ var init_dotenv_loader = __esm({
|
|
|
1385
1389
|
init_config_paths();
|
|
1386
1390
|
dotenvLoaded = false;
|
|
1387
1391
|
dotenvProjectRoot = null;
|
|
1392
|
+
dotenvHomeDir = null;
|
|
1388
1393
|
loadedEnvFiles = [];
|
|
1389
1394
|
loadedEnvKeys = /* @__PURE__ */ new Set();
|
|
1390
1395
|
loadedEnvValues = /* @__PURE__ */ new Map();
|
|
@@ -2099,33 +2104,33 @@ __export(config_exports, {
|
|
|
2099
2104
|
resetConfigCache: () => resetConfigCache,
|
|
2100
2105
|
resetDotenv: () => resetDotenv
|
|
2101
2106
|
});
|
|
2102
|
-
function getLLMApiKey() {
|
|
2103
|
-
return getResolvedMemoryLane().llm.apiKey;
|
|
2107
|
+
function getLLMApiKey(options = {}) {
|
|
2108
|
+
return getResolvedMemoryLane(options).llm.apiKey;
|
|
2104
2109
|
}
|
|
2105
|
-
function getLLMProvider() {
|
|
2106
|
-
const provider2 = getResolvedMemoryLane().llm.provider;
|
|
2110
|
+
function getLLMProvider(options = {}) {
|
|
2111
|
+
const provider2 = getResolvedMemoryLane(options).llm.provider;
|
|
2107
2112
|
if (provider2) return provider2;
|
|
2108
2113
|
if (process.env.ANTHROPIC_API_KEY && !process.env.OPENAI_API_KEY) return "anthropic";
|
|
2109
2114
|
if (process.env.OPENROUTER_API_KEY && !process.env.OPENAI_API_KEY) return "openrouter";
|
|
2110
2115
|
return "openai";
|
|
2111
2116
|
}
|
|
2112
|
-
function getLLMModel(providerDefault) {
|
|
2113
|
-
return getResolvedMemoryLane().llm.model || providerDefault;
|
|
2117
|
+
function getLLMModel(providerDefault, options = {}) {
|
|
2118
|
+
return getResolvedMemoryLane(options).llm.model || providerDefault;
|
|
2114
2119
|
}
|
|
2115
|
-
function getLLMBaseUrl(providerDefault) {
|
|
2116
|
-
return getResolvedMemoryLane().llm.baseUrl || providerDefault;
|
|
2120
|
+
function getLLMBaseUrl(providerDefault, options = {}) {
|
|
2121
|
+
return getResolvedMemoryLane(options).llm.baseUrl || providerDefault;
|
|
2117
2122
|
}
|
|
2118
|
-
function getAgentLLMApiKey() {
|
|
2119
|
-
return getResolvedAgentLane().apiKey;
|
|
2123
|
+
function getAgentLLMApiKey(options = {}) {
|
|
2124
|
+
return getResolvedAgentLane(options).apiKey;
|
|
2120
2125
|
}
|
|
2121
|
-
function getAgentLLMProvider() {
|
|
2122
|
-
return getResolvedAgentLane().provider || getLLMProvider();
|
|
2126
|
+
function getAgentLLMProvider(options = {}) {
|
|
2127
|
+
return getResolvedAgentLane(options).provider || getLLMProvider(options);
|
|
2123
2128
|
}
|
|
2124
|
-
function getAgentLLMModel(providerDefault) {
|
|
2125
|
-
return getResolvedAgentLane().model || getLLMModel(providerDefault);
|
|
2129
|
+
function getAgentLLMModel(providerDefault, options = {}) {
|
|
2130
|
+
return getResolvedAgentLane(options).model || getLLMModel(providerDefault, options);
|
|
2126
2131
|
}
|
|
2127
|
-
function getAgentLLMBaseUrl(providerDefault) {
|
|
2128
|
-
return getResolvedAgentLane().baseUrl || getLLMBaseUrl(providerDefault);
|
|
2132
|
+
function getAgentLLMBaseUrl(providerDefault, options = {}) {
|
|
2133
|
+
return getResolvedAgentLane(options).baseUrl || getLLMBaseUrl(providerDefault, options);
|
|
2129
2134
|
}
|
|
2130
2135
|
function getEmbeddingMode() {
|
|
2131
2136
|
const provider2 = getResolvedEmbeddingLane().provider?.toLowerCase()?.trim();
|
|
@@ -2285,18 +2290,19 @@ async function* callLLMWithToolsStream(messages, tools) {
|
|
|
2285
2290
|
}
|
|
2286
2291
|
function initLLM(options = {}) {
|
|
2287
2292
|
const scope = options.scope ?? "memory";
|
|
2288
|
-
const
|
|
2293
|
+
const configOptions = { projectRoot: options.projectRoot, homeDir: options.homeDir };
|
|
2294
|
+
const apiKey = scope === "agent" ? getAgentLLMApiKey(configOptions) : getLLMApiKey(configOptions);
|
|
2289
2295
|
if (!apiKey) {
|
|
2290
2296
|
currentConfig = null;
|
|
2291
2297
|
return null;
|
|
2292
2298
|
}
|
|
2293
|
-
const provider2 = scope === "agent" ? getAgentLLMProvider() : getLLMProvider();
|
|
2299
|
+
const provider2 = scope === "agent" ? getAgentLLMProvider(configOptions) : getLLMProvider(configOptions);
|
|
2294
2300
|
const defaults2 = PROVIDER_DEFAULTS[provider2] ?? PROVIDER_DEFAULTS.openai;
|
|
2295
2301
|
currentConfig = {
|
|
2296
2302
|
provider: provider2,
|
|
2297
2303
|
apiKey,
|
|
2298
|
-
model: scope === "agent" ? getAgentLLMModel(defaults2.model) : getLLMModel(defaults2.model),
|
|
2299
|
-
baseUrl: scope === "agent" ? getAgentLLMBaseUrl(defaults2.baseUrl) : getLLMBaseUrl(defaults2.baseUrl)
|
|
2304
|
+
model: scope === "agent" ? getAgentLLMModel(defaults2.model, configOptions) : getLLMModel(defaults2.model, configOptions),
|
|
2305
|
+
baseUrl: scope === "agent" ? getAgentLLMBaseUrl(defaults2.baseUrl, configOptions) : getLLMBaseUrl(defaults2.baseUrl, configOptions)
|
|
2300
2306
|
};
|
|
2301
2307
|
return currentConfig;
|
|
2302
2308
|
}
|
|
@@ -104,8 +104,10 @@ function loadEnvFile(filePath) {
|
|
|
104
104
|
loadedEnvFiles.push(filePath);
|
|
105
105
|
}
|
|
106
106
|
function loadDotenv(projectRoot, options = {}) {
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
const userHomeDir = options.userHomeDir ?? homedir();
|
|
108
|
+
const normalizedProjectRoot = projectRoot ?? null;
|
|
109
|
+
if (dotenvLoaded && dotenvProjectRoot === normalizedProjectRoot && dotenvHomeDir === userHomeDir) return;
|
|
110
|
+
if (dotenvLoaded && (dotenvProjectRoot !== normalizedProjectRoot || dotenvHomeDir !== userHomeDir)) {
|
|
109
111
|
resetDotenv();
|
|
110
112
|
}
|
|
111
113
|
loadedEnvFiles.length = 0;
|
|
@@ -114,9 +116,10 @@ function loadDotenv(projectRoot, options = {}) {
|
|
|
114
116
|
if (projectRoot) {
|
|
115
117
|
loadEnvFile(getProjectDotenvPath(projectRoot));
|
|
116
118
|
}
|
|
117
|
-
loadEnvFile(getGlobalDotenvPath(
|
|
119
|
+
loadEnvFile(getGlobalDotenvPath(userHomeDir));
|
|
118
120
|
dotenvLoaded = true;
|
|
119
|
-
dotenvProjectRoot =
|
|
121
|
+
dotenvProjectRoot = normalizedProjectRoot;
|
|
122
|
+
dotenvHomeDir = userHomeDir;
|
|
120
123
|
}
|
|
121
124
|
function resetDotenv() {
|
|
122
125
|
for (const key of injectedKeys) {
|
|
@@ -125,13 +128,14 @@ function resetDotenv() {
|
|
|
125
128
|
injectedKeys.clear();
|
|
126
129
|
dotenvLoaded = false;
|
|
127
130
|
dotenvProjectRoot = null;
|
|
131
|
+
dotenvHomeDir = null;
|
|
128
132
|
loadedEnvFiles.length = 0;
|
|
129
133
|
loadedEnvKeys.clear();
|
|
130
134
|
}
|
|
131
135
|
function getLoadedEnvFiles() {
|
|
132
136
|
return loadedEnvFiles;
|
|
133
137
|
}
|
|
134
|
-
var dotenvLoaded, dotenvProjectRoot, loadedEnvFiles, loadedEnvKeys, loadedEnvValues, injectedKeys;
|
|
138
|
+
var dotenvLoaded, dotenvProjectRoot, dotenvHomeDir, loadedEnvFiles, loadedEnvKeys, loadedEnvValues, injectedKeys;
|
|
135
139
|
var init_dotenv_loader = __esm({
|
|
136
140
|
"src/config/dotenv-loader.ts"() {
|
|
137
141
|
"use strict";
|
|
@@ -139,6 +143,7 @@ var init_dotenv_loader = __esm({
|
|
|
139
143
|
init_config_paths();
|
|
140
144
|
dotenvLoaded = false;
|
|
141
145
|
dotenvProjectRoot = null;
|
|
146
|
+
dotenvHomeDir = null;
|
|
142
147
|
loadedEnvFiles = [];
|
|
143
148
|
loadedEnvKeys = /* @__PURE__ */ new Set();
|
|
144
149
|
loadedEnvValues = /* @__PURE__ */ new Map();
|
|
@@ -3355,33 +3360,33 @@ __export(config_exports, {
|
|
|
3355
3360
|
resetConfigCache: () => resetConfigCache,
|
|
3356
3361
|
resetDotenv: () => resetDotenv
|
|
3357
3362
|
});
|
|
3358
|
-
function getLLMApiKey() {
|
|
3359
|
-
return getResolvedMemoryLane().llm.apiKey;
|
|
3363
|
+
function getLLMApiKey(options = {}) {
|
|
3364
|
+
return getResolvedMemoryLane(options).llm.apiKey;
|
|
3360
3365
|
}
|
|
3361
|
-
function getLLMProvider() {
|
|
3362
|
-
const provider2 = getResolvedMemoryLane().llm.provider;
|
|
3366
|
+
function getLLMProvider(options = {}) {
|
|
3367
|
+
const provider2 = getResolvedMemoryLane(options).llm.provider;
|
|
3363
3368
|
if (provider2) return provider2;
|
|
3364
3369
|
if (process.env.ANTHROPIC_API_KEY && !process.env.OPENAI_API_KEY) return "anthropic";
|
|
3365
3370
|
if (process.env.OPENROUTER_API_KEY && !process.env.OPENAI_API_KEY) return "openrouter";
|
|
3366
3371
|
return "openai";
|
|
3367
3372
|
}
|
|
3368
|
-
function getLLMModel(providerDefault) {
|
|
3369
|
-
return getResolvedMemoryLane().llm.model || providerDefault;
|
|
3373
|
+
function getLLMModel(providerDefault, options = {}) {
|
|
3374
|
+
return getResolvedMemoryLane(options).llm.model || providerDefault;
|
|
3370
3375
|
}
|
|
3371
|
-
function getLLMBaseUrl(providerDefault) {
|
|
3372
|
-
return getResolvedMemoryLane().llm.baseUrl || providerDefault;
|
|
3376
|
+
function getLLMBaseUrl(providerDefault, options = {}) {
|
|
3377
|
+
return getResolvedMemoryLane(options).llm.baseUrl || providerDefault;
|
|
3373
3378
|
}
|
|
3374
|
-
function getAgentLLMApiKey() {
|
|
3375
|
-
return getResolvedAgentLane().apiKey;
|
|
3379
|
+
function getAgentLLMApiKey(options = {}) {
|
|
3380
|
+
return getResolvedAgentLane(options).apiKey;
|
|
3376
3381
|
}
|
|
3377
|
-
function getAgentLLMProvider() {
|
|
3378
|
-
return getResolvedAgentLane().provider || getLLMProvider();
|
|
3382
|
+
function getAgentLLMProvider(options = {}) {
|
|
3383
|
+
return getResolvedAgentLane(options).provider || getLLMProvider(options);
|
|
3379
3384
|
}
|
|
3380
|
-
function getAgentLLMModel(providerDefault) {
|
|
3381
|
-
return getResolvedAgentLane().model || getLLMModel(providerDefault);
|
|
3385
|
+
function getAgentLLMModel(providerDefault, options = {}) {
|
|
3386
|
+
return getResolvedAgentLane(options).model || getLLMModel(providerDefault, options);
|
|
3382
3387
|
}
|
|
3383
|
-
function getAgentLLMBaseUrl(providerDefault) {
|
|
3384
|
-
return getResolvedAgentLane().baseUrl || getLLMBaseUrl(providerDefault);
|
|
3388
|
+
function getAgentLLMBaseUrl(providerDefault, options = {}) {
|
|
3389
|
+
return getResolvedAgentLane(options).baseUrl || getLLMBaseUrl(providerDefault, options);
|
|
3385
3390
|
}
|
|
3386
3391
|
function getEmbeddingMode() {
|
|
3387
3392
|
const provider2 = getResolvedEmbeddingLane().provider?.toLowerCase()?.trim();
|
|
@@ -5640,18 +5645,19 @@ async function* callLLMWithToolsStream(messages, tools) {
|
|
|
5640
5645
|
}
|
|
5641
5646
|
function initLLM(options = {}) {
|
|
5642
5647
|
const scope = options.scope ?? "memory";
|
|
5643
|
-
const
|
|
5648
|
+
const configOptions = { projectRoot: options.projectRoot, homeDir: options.homeDir };
|
|
5649
|
+
const apiKey = scope === "agent" ? getAgentLLMApiKey(configOptions) : getLLMApiKey(configOptions);
|
|
5644
5650
|
if (!apiKey) {
|
|
5645
5651
|
currentConfig = null;
|
|
5646
5652
|
return null;
|
|
5647
5653
|
}
|
|
5648
|
-
const provider2 = scope === "agent" ? getAgentLLMProvider() : getLLMProvider();
|
|
5654
|
+
const provider2 = scope === "agent" ? getAgentLLMProvider(configOptions) : getLLMProvider(configOptions);
|
|
5649
5655
|
const defaults2 = PROVIDER_DEFAULTS[provider2] ?? PROVIDER_DEFAULTS.openai;
|
|
5650
5656
|
currentConfig = {
|
|
5651
5657
|
provider: provider2,
|
|
5652
5658
|
apiKey,
|
|
5653
|
-
model: scope === "agent" ? getAgentLLMModel(defaults2.model) : getLLMModel(defaults2.model),
|
|
5654
|
-
baseUrl: scope === "agent" ? getAgentLLMBaseUrl(defaults2.baseUrl) : getLLMBaseUrl(defaults2.baseUrl)
|
|
5659
|
+
model: scope === "agent" ? getAgentLLMModel(defaults2.model, configOptions) : getLLMModel(defaults2.model, configOptions),
|
|
5660
|
+
baseUrl: scope === "agent" ? getAgentLLMBaseUrl(defaults2.baseUrl, configOptions) : getLLMBaseUrl(defaults2.baseUrl, configOptions)
|
|
5655
5661
|
};
|
|
5656
5662
|
return currentConfig;
|
|
5657
5663
|
}
|
|
@@ -104,8 +104,10 @@ function loadEnvFile(filePath) {
|
|
|
104
104
|
loadedEnvFiles.push(filePath);
|
|
105
105
|
}
|
|
106
106
|
function loadDotenv(projectRoot, options = {}) {
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
const userHomeDir = options.userHomeDir ?? homedir();
|
|
108
|
+
const normalizedProjectRoot = projectRoot ?? null;
|
|
109
|
+
if (dotenvLoaded && dotenvProjectRoot === normalizedProjectRoot && dotenvHomeDir === userHomeDir) return;
|
|
110
|
+
if (dotenvLoaded && (dotenvProjectRoot !== normalizedProjectRoot || dotenvHomeDir !== userHomeDir)) {
|
|
109
111
|
resetDotenv();
|
|
110
112
|
}
|
|
111
113
|
loadedEnvFiles.length = 0;
|
|
@@ -114,9 +116,10 @@ function loadDotenv(projectRoot, options = {}) {
|
|
|
114
116
|
if (projectRoot) {
|
|
115
117
|
loadEnvFile(getProjectDotenvPath(projectRoot));
|
|
116
118
|
}
|
|
117
|
-
loadEnvFile(getGlobalDotenvPath(
|
|
119
|
+
loadEnvFile(getGlobalDotenvPath(userHomeDir));
|
|
118
120
|
dotenvLoaded = true;
|
|
119
|
-
dotenvProjectRoot =
|
|
121
|
+
dotenvProjectRoot = normalizedProjectRoot;
|
|
122
|
+
dotenvHomeDir = userHomeDir;
|
|
120
123
|
}
|
|
121
124
|
function resetDotenv() {
|
|
122
125
|
for (const key of injectedKeys) {
|
|
@@ -125,13 +128,14 @@ function resetDotenv() {
|
|
|
125
128
|
injectedKeys.clear();
|
|
126
129
|
dotenvLoaded = false;
|
|
127
130
|
dotenvProjectRoot = null;
|
|
131
|
+
dotenvHomeDir = null;
|
|
128
132
|
loadedEnvFiles.length = 0;
|
|
129
133
|
loadedEnvKeys.clear();
|
|
130
134
|
}
|
|
131
135
|
function getLoadedEnvFiles() {
|
|
132
136
|
return loadedEnvFiles;
|
|
133
137
|
}
|
|
134
|
-
var dotenvLoaded, dotenvProjectRoot, loadedEnvFiles, loadedEnvKeys, loadedEnvValues, injectedKeys;
|
|
138
|
+
var dotenvLoaded, dotenvProjectRoot, dotenvHomeDir, loadedEnvFiles, loadedEnvKeys, loadedEnvValues, injectedKeys;
|
|
135
139
|
var init_dotenv_loader = __esm({
|
|
136
140
|
"src/config/dotenv-loader.ts"() {
|
|
137
141
|
"use strict";
|
|
@@ -139,6 +143,7 @@ var init_dotenv_loader = __esm({
|
|
|
139
143
|
init_config_paths();
|
|
140
144
|
dotenvLoaded = false;
|
|
141
145
|
dotenvProjectRoot = null;
|
|
146
|
+
dotenvHomeDir = null;
|
|
142
147
|
loadedEnvFiles = [];
|
|
143
148
|
loadedEnvKeys = /* @__PURE__ */ new Set();
|
|
144
149
|
loadedEnvValues = /* @__PURE__ */ new Map();
|
|
@@ -2372,33 +2377,33 @@ __export(config_exports, {
|
|
|
2372
2377
|
resetConfigCache: () => resetConfigCache,
|
|
2373
2378
|
resetDotenv: () => resetDotenv
|
|
2374
2379
|
});
|
|
2375
|
-
function getLLMApiKey() {
|
|
2376
|
-
return getResolvedMemoryLane().llm.apiKey;
|
|
2380
|
+
function getLLMApiKey(options = {}) {
|
|
2381
|
+
return getResolvedMemoryLane(options).llm.apiKey;
|
|
2377
2382
|
}
|
|
2378
|
-
function getLLMProvider() {
|
|
2379
|
-
const provider2 = getResolvedMemoryLane().llm.provider;
|
|
2383
|
+
function getLLMProvider(options = {}) {
|
|
2384
|
+
const provider2 = getResolvedMemoryLane(options).llm.provider;
|
|
2380
2385
|
if (provider2) return provider2;
|
|
2381
2386
|
if (process.env.ANTHROPIC_API_KEY && !process.env.OPENAI_API_KEY) return "anthropic";
|
|
2382
2387
|
if (process.env.OPENROUTER_API_KEY && !process.env.OPENAI_API_KEY) return "openrouter";
|
|
2383
2388
|
return "openai";
|
|
2384
2389
|
}
|
|
2385
|
-
function getLLMModel(providerDefault) {
|
|
2386
|
-
return getResolvedMemoryLane().llm.model || providerDefault;
|
|
2390
|
+
function getLLMModel(providerDefault, options = {}) {
|
|
2391
|
+
return getResolvedMemoryLane(options).llm.model || providerDefault;
|
|
2387
2392
|
}
|
|
2388
|
-
function getLLMBaseUrl(providerDefault) {
|
|
2389
|
-
return getResolvedMemoryLane().llm.baseUrl || providerDefault;
|
|
2393
|
+
function getLLMBaseUrl(providerDefault, options = {}) {
|
|
2394
|
+
return getResolvedMemoryLane(options).llm.baseUrl || providerDefault;
|
|
2390
2395
|
}
|
|
2391
|
-
function getAgentLLMApiKey() {
|
|
2392
|
-
return getResolvedAgentLane().apiKey;
|
|
2396
|
+
function getAgentLLMApiKey(options = {}) {
|
|
2397
|
+
return getResolvedAgentLane(options).apiKey;
|
|
2393
2398
|
}
|
|
2394
|
-
function getAgentLLMProvider() {
|
|
2395
|
-
return getResolvedAgentLane().provider || getLLMProvider();
|
|
2399
|
+
function getAgentLLMProvider(options = {}) {
|
|
2400
|
+
return getResolvedAgentLane(options).provider || getLLMProvider(options);
|
|
2396
2401
|
}
|
|
2397
|
-
function getAgentLLMModel(providerDefault) {
|
|
2398
|
-
return getResolvedAgentLane().model || getLLMModel(providerDefault);
|
|
2402
|
+
function getAgentLLMModel(providerDefault, options = {}) {
|
|
2403
|
+
return getResolvedAgentLane(options).model || getLLMModel(providerDefault, options);
|
|
2399
2404
|
}
|
|
2400
|
-
function getAgentLLMBaseUrl(providerDefault) {
|
|
2401
|
-
return getResolvedAgentLane().baseUrl || getLLMBaseUrl(providerDefault);
|
|
2405
|
+
function getAgentLLMBaseUrl(providerDefault, options = {}) {
|
|
2406
|
+
return getResolvedAgentLane(options).baseUrl || getLLMBaseUrl(providerDefault, options);
|
|
2402
2407
|
}
|
|
2403
2408
|
function getEmbeddingMode() {
|
|
2404
2409
|
const provider2 = getResolvedEmbeddingLane().provider?.toLowerCase()?.trim();
|
|
@@ -4657,18 +4662,19 @@ async function* callLLMWithToolsStream(messages, tools) {
|
|
|
4657
4662
|
}
|
|
4658
4663
|
function initLLM(options = {}) {
|
|
4659
4664
|
const scope = options.scope ?? "memory";
|
|
4660
|
-
const
|
|
4665
|
+
const configOptions = { projectRoot: options.projectRoot, homeDir: options.homeDir };
|
|
4666
|
+
const apiKey = scope === "agent" ? getAgentLLMApiKey(configOptions) : getLLMApiKey(configOptions);
|
|
4661
4667
|
if (!apiKey) {
|
|
4662
4668
|
currentConfig = null;
|
|
4663
4669
|
return null;
|
|
4664
4670
|
}
|
|
4665
|
-
const provider2 = scope === "agent" ? getAgentLLMProvider() : getLLMProvider();
|
|
4671
|
+
const provider2 = scope === "agent" ? getAgentLLMProvider(configOptions) : getLLMProvider(configOptions);
|
|
4666
4672
|
const defaults2 = PROVIDER_DEFAULTS[provider2] ?? PROVIDER_DEFAULTS.openai;
|
|
4667
4673
|
currentConfig = {
|
|
4668
4674
|
provider: provider2,
|
|
4669
4675
|
apiKey,
|
|
4670
|
-
model: scope === "agent" ? getAgentLLMModel(defaults2.model) : getLLMModel(defaults2.model),
|
|
4671
|
-
baseUrl: scope === "agent" ? getAgentLLMBaseUrl(defaults2.baseUrl) : getLLMBaseUrl(defaults2.baseUrl)
|
|
4676
|
+
model: scope === "agent" ? getAgentLLMModel(defaults2.model, configOptions) : getLLMModel(defaults2.model, configOptions),
|
|
4677
|
+
baseUrl: scope === "agent" ? getAgentLLMBaseUrl(defaults2.baseUrl, configOptions) : getLLMBaseUrl(defaults2.baseUrl, configOptions)
|
|
4672
4678
|
};
|
|
4673
4679
|
return currentConfig;
|
|
4674
4680
|
}
|
|
@@ -4,6 +4,42 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [1.8.3] - 2026-08-25
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- **Stdio MCP startup gate** -- `memorix serve` now reads and bounds
|
|
11
|
+
newline-delimited JSON-RPC input before project initialization completes.
|
|
12
|
+
Early `server/discover` requests receive the complete discovery result, while
|
|
13
|
+
initialize, notifications, responses, and versionless tool requests replay
|
|
14
|
+
through the pinned SDK transport in input order without duplicate handling.
|
|
15
|
+
|
|
16
|
+
### MCP Compatibility
|
|
17
|
+
- **Stable cold-start discovery** -- real stdio CLI startup now supports
|
|
18
|
+
pre-initialize discovery within the startup window and preserves legacy
|
|
19
|
+
initialize plus versionless `tools/list`/`tools/call` behavior. Tasks,
|
|
20
|
+
subscriptions, list-response caching, and modern non-discovery result
|
|
21
|
+
metadata remain unsupported or partial.
|
|
22
|
+
|
|
23
|
+
## [1.8.2] - 2026-08-25
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
- **Dashboard deduplication initialization (#248)** -- standalone and HTTP
|
|
27
|
+
maintenance previews now idempotently resolve the selected project's memory
|
|
28
|
+
LLM from TOML and `.env`, clear stale cross-project configuration, and keep
|
|
29
|
+
credentials out of responses.
|
|
30
|
+
- **CodeGraph capability fallback (#250)** -- a failed or invalid `context`
|
|
31
|
+
probe now tries the official `explore` CLI with bounded, shell-free spawning.
|
|
32
|
+
Only validated paths, symbols, and relationships can select the external
|
|
33
|
+
provider; separate context/explore diagnostics explain Lite fallback.
|
|
34
|
+
|
|
35
|
+
### MCP Compatibility
|
|
36
|
+
- **Discovery adapter (#249)** -- the stdio server registers a real low-level
|
|
37
|
+
`server/discover` handler that returns the required 2026-07-28
|
|
38
|
+
`DiscoverResult` before `initialize`. Legacy 2025 initialize and versionless
|
|
39
|
+
`tools/list`/`tools/call` remain supported through the SDK's legacy envelopes.
|
|
40
|
+
Tasks, subscriptions, and list-response caching remain unsupported and are
|
|
41
|
+
not advertised.
|
|
42
|
+
|
|
7
43
|
## [1.8.1] - 2026-08-24
|
|
8
44
|
|
|
9
45
|
### Changed
|