memorix 1.9.8 → 1.9.10
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 +17 -0
- package/README.md +2 -0
- package/README.zh-CN.md +2 -0
- package/dist/cli/index.js +125 -31
- package/dist/index.js +117 -31
- package/dist/maintenance-runner.js +22 -5
- package/dist/media-audio-runner.js +22 -5
- package/dist/media-video-runner.js +22 -5
- package/dist/memcode-runtime/CHANGELOG.md +17 -0
- package/dist/sdk.js +116 -30
- package/dist/vector-backfill-runner.js +22 -5
- package/docs/CONFIGURATION.md +22 -0
- package/docs/DEVELOPMENT.md +1 -1
- package/docs/INTEGRATIONS.md +1 -1
- package/docs/README.md +1 -1
- package/docs/SETUP.md +1 -1
- package/package.json +1 -1
- package/plugins/antigravity/memorix/plugin.json +1 -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 +2 -2
- package/src/cli/commands/init.ts +7 -1
- package/src/cli/tui/ConfigureView.tsx +2 -0
- package/src/config/dotenv-loader.ts +1 -0
- package/src/config/resolved-config.ts +19 -5
- package/src/config/yaml-loader.ts +2 -2
- package/src/config.ts +5 -1
- package/src/dashboard/server.ts +3 -0
- package/src/hooks/installers/index.ts +89 -21
- package/src/llm/provider.ts +2 -1
- package/src/multimodal/image-loader.ts +2 -2
|
@@ -2089,6 +2089,7 @@ function getResolvedConfig(options = {}) {
|
|
|
2089
2089
|
const legacy = loadFileConfig(homeDir);
|
|
2090
2090
|
const embeddingBaseUrl = first(process.env.MEMORIX_EMBEDDING_BASE_URL, toml.embedding?.base_url, yaml.embedding?.baseUrl, legacy.embeddingApi?.baseUrl);
|
|
2091
2091
|
const openRouterEmbeddingApiKey = isOpenRouterUrl(embeddingBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
2092
|
+
const requestyEmbeddingApiKey = isRequestyUrl(embeddingBaseUrl) ? process.env.REQUESTY_API_KEY : void 0;
|
|
2092
2093
|
const memoryLlmProvider = first(
|
|
2093
2094
|
process.env.MEMORIX_LLM_PROVIDER,
|
|
2094
2095
|
toml.memory?.llm?.provider,
|
|
@@ -2109,16 +2110,18 @@ function getResolvedConfig(options = {}) {
|
|
|
2109
2110
|
);
|
|
2110
2111
|
const openRouterMemoryLlmApiKey = isOpenRouterMemoryLane(memoryLlmProvider, memoryLlmBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
2111
2112
|
const isAtlasCloud = memoryLlmProvider === "atlascloud";
|
|
2113
|
+
const isRequesty = memoryLlmProvider === "requesty";
|
|
2114
|
+
const usesPresetKeyOnly = isAtlasCloud || isRequesty;
|
|
2112
2115
|
const memoryLlmApiKey = first(
|
|
2113
2116
|
process.env.MEMORIX_LLM_API_KEY,
|
|
2114
2117
|
process.env.MEMORIX_API_KEY,
|
|
2115
2118
|
toml.memory?.llm?.api_key,
|
|
2116
2119
|
yaml.llm?.apiKey,
|
|
2117
2120
|
legacy.llm?.apiKey,
|
|
2118
|
-
// Never borrow another provider's credentials for the Atlas Cloud
|
|
2119
|
-
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : process.env.OPENAI_API_KEY,
|
|
2120
|
-
|
|
2121
|
-
|
|
2121
|
+
// Never borrow another provider's credentials for the Atlas Cloud or Requesty presets.
|
|
2122
|
+
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : isRequesty ? process.env.REQUESTY_API_KEY : process.env.OPENAI_API_KEY,
|
|
2123
|
+
usesPresetKeyOnly ? void 0 : process.env.ANTHROPIC_API_KEY,
|
|
2124
|
+
usesPresetKeyOnly ? void 0 : openRouterMemoryLlmApiKey
|
|
2122
2125
|
);
|
|
2123
2126
|
const resolved = {
|
|
2124
2127
|
agent: {
|
|
@@ -2167,7 +2170,7 @@ function getResolvedConfig(options = {}) {
|
|
|
2167
2170
|
provider: first(process.env.MEMORIX_EMBEDDING, toml.embedding?.provider, yaml.embedding?.provider, legacy.embedding, "off"),
|
|
2168
2171
|
model: first(process.env.MEMORIX_EMBEDDING_MODEL, toml.embedding?.model, yaml.embedding?.model, legacy.embeddingApi?.model),
|
|
2169
2172
|
baseUrl: embeddingBaseUrl,
|
|
2170
|
-
apiKey: first(process.env.MEMORIX_EMBEDDING_API_KEY, toml.embedding?.api_key, yaml.embedding?.apiKey, legacy.embeddingApi?.apiKey, openRouterEmbeddingApiKey),
|
|
2173
|
+
apiKey: first(process.env.MEMORIX_EMBEDDING_API_KEY, toml.embedding?.api_key, yaml.embedding?.apiKey, legacy.embeddingApi?.apiKey, openRouterEmbeddingApiKey, requestyEmbeddingApiKey),
|
|
2171
2174
|
dimensions: firstNumber(parseNumber(process.env.MEMORIX_EMBEDDING_DIMENSIONS), toml.embedding?.dimensions, yaml.embedding?.dimensions, legacy.embeddingApi?.dimensions)
|
|
2172
2175
|
},
|
|
2173
2176
|
rerank: resolveRerankLane({
|
|
@@ -2298,6 +2301,7 @@ function getEnvSourceNames() {
|
|
|
2298
2301
|
"MEMORIX_CODEGRAPH_EXTERNAL_COMMAND",
|
|
2299
2302
|
"MEMORIX_CODEGRAPH_EXTERNAL_TIMEOUT_MS",
|
|
2300
2303
|
"OPENROUTER_API_KEY",
|
|
2304
|
+
"REQUESTY_API_KEY",
|
|
2301
2305
|
"ATLASCLOUD_API_KEY"
|
|
2302
2306
|
].filter((name) => process.env[name]);
|
|
2303
2307
|
}
|
|
@@ -2310,6 +2314,15 @@ function isOpenRouterUrl(value) {
|
|
|
2310
2314
|
return /(^|\.)openrouter\.ai(?::|\/|$)/i.test(value);
|
|
2311
2315
|
}
|
|
2312
2316
|
}
|
|
2317
|
+
function isRequestyUrl(value) {
|
|
2318
|
+
if (!value) return false;
|
|
2319
|
+
try {
|
|
2320
|
+
const url = new URL(value);
|
|
2321
|
+
return url.hostname.toLowerCase() === "requesty.ai" || url.hostname.toLowerCase().endsWith(".requesty.ai");
|
|
2322
|
+
} catch {
|
|
2323
|
+
return /(^|\.)requesty\.ai(?::|\/|$)/i.test(value);
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2313
2326
|
function isOpenRouterMemoryLane(provider2, baseUrl) {
|
|
2314
2327
|
return provider2?.trim().toLowerCase() === "openrouter" || isOpenRouterUrl(baseUrl);
|
|
2315
2328
|
}
|
|
@@ -2464,6 +2477,9 @@ function defaultEmbeddingModelFor(baseUrl, explicitModel) {
|
|
|
2464
2477
|
if (url && (url.hostname === "openrouter.ai" || url.hostname.endsWith(".openrouter.ai"))) {
|
|
2465
2478
|
return "qwen/qwen3-embedding-8b";
|
|
2466
2479
|
}
|
|
2480
|
+
if (url && (url.hostname === "requesty.ai" || url.hostname.endsWith(".requesty.ai"))) {
|
|
2481
|
+
return "openai/text-embedding-3-small";
|
|
2482
|
+
}
|
|
2467
2483
|
} catch {
|
|
2468
2484
|
}
|
|
2469
2485
|
return "text-embedding-3-small";
|
|
@@ -3129,6 +3145,7 @@ var init_provider = __esm({
|
|
|
3129
3145
|
openai: { baseUrl: "https://api.openai.com/v1", model: "gpt-4.1-nano" },
|
|
3130
3146
|
anthropic: { baseUrl: "https://api.anthropic.com/v1", model: "claude-3-5-haiku-latest" },
|
|
3131
3147
|
openrouter: { baseUrl: "https://openrouter.ai/api/v1", model: "openai/gpt-4.1-nano" },
|
|
3148
|
+
requesty: { baseUrl: "https://router.requesty.ai/v1", model: "openai/gpt-4.1-nano" },
|
|
3132
3149
|
atlascloud: { baseUrl: "https://api.atlascloud.ai/v1", model: "deepseek-ai/deepseek-v3.2" },
|
|
3133
3150
|
custom: { baseUrl: "http://localhost:11434/v1", model: "llama3" }
|
|
3134
3151
|
};
|
|
@@ -3372,6 +3372,7 @@ function getResolvedConfig(options = {}) {
|
|
|
3372
3372
|
const legacy = loadFileConfig(homeDir);
|
|
3373
3373
|
const embeddingBaseUrl = first(process.env.MEMORIX_EMBEDDING_BASE_URL, toml.embedding?.base_url, yaml.embedding?.baseUrl, legacy.embeddingApi?.baseUrl);
|
|
3374
3374
|
const openRouterEmbeddingApiKey = isOpenRouterUrl(embeddingBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
3375
|
+
const requestyEmbeddingApiKey = isRequestyUrl(embeddingBaseUrl) ? process.env.REQUESTY_API_KEY : void 0;
|
|
3375
3376
|
const memoryLlmProvider = first(
|
|
3376
3377
|
process.env.MEMORIX_LLM_PROVIDER,
|
|
3377
3378
|
toml.memory?.llm?.provider,
|
|
@@ -3392,16 +3393,18 @@ function getResolvedConfig(options = {}) {
|
|
|
3392
3393
|
);
|
|
3393
3394
|
const openRouterMemoryLlmApiKey = isOpenRouterMemoryLane(memoryLlmProvider, memoryLlmBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
3394
3395
|
const isAtlasCloud = memoryLlmProvider === "atlascloud";
|
|
3396
|
+
const isRequesty = memoryLlmProvider === "requesty";
|
|
3397
|
+
const usesPresetKeyOnly = isAtlasCloud || isRequesty;
|
|
3395
3398
|
const memoryLlmApiKey = first(
|
|
3396
3399
|
process.env.MEMORIX_LLM_API_KEY,
|
|
3397
3400
|
process.env.MEMORIX_API_KEY,
|
|
3398
3401
|
toml.memory?.llm?.api_key,
|
|
3399
3402
|
yaml.llm?.apiKey,
|
|
3400
3403
|
legacy.llm?.apiKey,
|
|
3401
|
-
// Never borrow another provider's credentials for the Atlas Cloud
|
|
3402
|
-
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : process.env.OPENAI_API_KEY,
|
|
3403
|
-
|
|
3404
|
-
|
|
3404
|
+
// Never borrow another provider's credentials for the Atlas Cloud or Requesty presets.
|
|
3405
|
+
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : isRequesty ? process.env.REQUESTY_API_KEY : process.env.OPENAI_API_KEY,
|
|
3406
|
+
usesPresetKeyOnly ? void 0 : process.env.ANTHROPIC_API_KEY,
|
|
3407
|
+
usesPresetKeyOnly ? void 0 : openRouterMemoryLlmApiKey
|
|
3405
3408
|
);
|
|
3406
3409
|
const resolved = {
|
|
3407
3410
|
agent: {
|
|
@@ -3450,7 +3453,7 @@ function getResolvedConfig(options = {}) {
|
|
|
3450
3453
|
provider: first(process.env.MEMORIX_EMBEDDING, toml.embedding?.provider, yaml.embedding?.provider, legacy.embedding, "off"),
|
|
3451
3454
|
model: first(process.env.MEMORIX_EMBEDDING_MODEL, toml.embedding?.model, yaml.embedding?.model, legacy.embeddingApi?.model),
|
|
3452
3455
|
baseUrl: embeddingBaseUrl,
|
|
3453
|
-
apiKey: first(process.env.MEMORIX_EMBEDDING_API_KEY, toml.embedding?.api_key, yaml.embedding?.apiKey, legacy.embeddingApi?.apiKey, openRouterEmbeddingApiKey),
|
|
3456
|
+
apiKey: first(process.env.MEMORIX_EMBEDDING_API_KEY, toml.embedding?.api_key, yaml.embedding?.apiKey, legacy.embeddingApi?.apiKey, openRouterEmbeddingApiKey, requestyEmbeddingApiKey),
|
|
3454
3457
|
dimensions: firstNumber(parseNumber(process.env.MEMORIX_EMBEDDING_DIMENSIONS), toml.embedding?.dimensions, yaml.embedding?.dimensions, legacy.embeddingApi?.dimensions)
|
|
3455
3458
|
},
|
|
3456
3459
|
rerank: resolveRerankLane({
|
|
@@ -3581,6 +3584,7 @@ function getEnvSourceNames() {
|
|
|
3581
3584
|
"MEMORIX_CODEGRAPH_EXTERNAL_COMMAND",
|
|
3582
3585
|
"MEMORIX_CODEGRAPH_EXTERNAL_TIMEOUT_MS",
|
|
3583
3586
|
"OPENROUTER_API_KEY",
|
|
3587
|
+
"REQUESTY_API_KEY",
|
|
3584
3588
|
"ATLASCLOUD_API_KEY"
|
|
3585
3589
|
].filter((name) => process.env[name]);
|
|
3586
3590
|
}
|
|
@@ -3593,6 +3597,15 @@ function isOpenRouterUrl(value) {
|
|
|
3593
3597
|
return /(^|\.)openrouter\.ai(?::|\/|$)/i.test(value);
|
|
3594
3598
|
}
|
|
3595
3599
|
}
|
|
3600
|
+
function isRequestyUrl(value) {
|
|
3601
|
+
if (!value) return false;
|
|
3602
|
+
try {
|
|
3603
|
+
const url = new URL(value);
|
|
3604
|
+
return url.hostname.toLowerCase() === "requesty.ai" || url.hostname.toLowerCase().endsWith(".requesty.ai");
|
|
3605
|
+
} catch {
|
|
3606
|
+
return /(^|\.)requesty\.ai(?::|\/|$)/i.test(value);
|
|
3607
|
+
}
|
|
3608
|
+
}
|
|
3596
3609
|
function isOpenRouterMemoryLane(provider2, baseUrl) {
|
|
3597
3610
|
return provider2?.trim().toLowerCase() === "openrouter" || isOpenRouterUrl(baseUrl);
|
|
3598
3611
|
}
|
|
@@ -3747,6 +3760,9 @@ function defaultEmbeddingModelFor(baseUrl, explicitModel) {
|
|
|
3747
3760
|
if (url && (url.hostname === "openrouter.ai" || url.hostname.endsWith(".openrouter.ai"))) {
|
|
3748
3761
|
return "qwen/qwen3-embedding-8b";
|
|
3749
3762
|
}
|
|
3763
|
+
if (url && (url.hostname === "requesty.ai" || url.hostname.endsWith(".requesty.ai"))) {
|
|
3764
|
+
return "openai/text-embedding-3-small";
|
|
3765
|
+
}
|
|
3750
3766
|
} catch {
|
|
3751
3767
|
}
|
|
3752
3768
|
return "text-embedding-3-small";
|
|
@@ -6561,6 +6577,7 @@ var init_provider2 = __esm({
|
|
|
6561
6577
|
openai: { baseUrl: "https://api.openai.com/v1", model: "gpt-4.1-nano" },
|
|
6562
6578
|
anthropic: { baseUrl: "https://api.anthropic.com/v1", model: "claude-3-5-haiku-latest" },
|
|
6563
6579
|
openrouter: { baseUrl: "https://openrouter.ai/api/v1", model: "openai/gpt-4.1-nano" },
|
|
6580
|
+
requesty: { baseUrl: "https://router.requesty.ai/v1", model: "openai/gpt-4.1-nano" },
|
|
6564
6581
|
atlascloud: { baseUrl: "https://api.atlascloud.ai/v1", model: "deepseek-ai/deepseek-v3.2" },
|
|
6565
6582
|
custom: { baseUrl: "http://localhost:11434/v1", model: "llama3" }
|
|
6566
6583
|
};
|
|
@@ -2384,6 +2384,7 @@ function getResolvedConfig(options = {}) {
|
|
|
2384
2384
|
const legacy = loadFileConfig(homeDir);
|
|
2385
2385
|
const embeddingBaseUrl = first(process.env.MEMORIX_EMBEDDING_BASE_URL, toml.embedding?.base_url, yaml.embedding?.baseUrl, legacy.embeddingApi?.baseUrl);
|
|
2386
2386
|
const openRouterEmbeddingApiKey = isOpenRouterUrl(embeddingBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
2387
|
+
const requestyEmbeddingApiKey = isRequestyUrl(embeddingBaseUrl) ? process.env.REQUESTY_API_KEY : void 0;
|
|
2387
2388
|
const memoryLlmProvider = first(
|
|
2388
2389
|
process.env.MEMORIX_LLM_PROVIDER,
|
|
2389
2390
|
toml.memory?.llm?.provider,
|
|
@@ -2404,16 +2405,18 @@ function getResolvedConfig(options = {}) {
|
|
|
2404
2405
|
);
|
|
2405
2406
|
const openRouterMemoryLlmApiKey = isOpenRouterMemoryLane(memoryLlmProvider, memoryLlmBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
2406
2407
|
const isAtlasCloud = memoryLlmProvider === "atlascloud";
|
|
2408
|
+
const isRequesty = memoryLlmProvider === "requesty";
|
|
2409
|
+
const usesPresetKeyOnly = isAtlasCloud || isRequesty;
|
|
2407
2410
|
const memoryLlmApiKey = first(
|
|
2408
2411
|
process.env.MEMORIX_LLM_API_KEY,
|
|
2409
2412
|
process.env.MEMORIX_API_KEY,
|
|
2410
2413
|
toml.memory?.llm?.api_key,
|
|
2411
2414
|
yaml.llm?.apiKey,
|
|
2412
2415
|
legacy.llm?.apiKey,
|
|
2413
|
-
// Never borrow another provider's credentials for the Atlas Cloud
|
|
2414
|
-
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : process.env.OPENAI_API_KEY,
|
|
2415
|
-
|
|
2416
|
-
|
|
2416
|
+
// Never borrow another provider's credentials for the Atlas Cloud or Requesty presets.
|
|
2417
|
+
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : isRequesty ? process.env.REQUESTY_API_KEY : process.env.OPENAI_API_KEY,
|
|
2418
|
+
usesPresetKeyOnly ? void 0 : process.env.ANTHROPIC_API_KEY,
|
|
2419
|
+
usesPresetKeyOnly ? void 0 : openRouterMemoryLlmApiKey
|
|
2417
2420
|
);
|
|
2418
2421
|
const resolved = {
|
|
2419
2422
|
agent: {
|
|
@@ -2462,7 +2465,7 @@ function getResolvedConfig(options = {}) {
|
|
|
2462
2465
|
provider: first(process.env.MEMORIX_EMBEDDING, toml.embedding?.provider, yaml.embedding?.provider, legacy.embedding, "off"),
|
|
2463
2466
|
model: first(process.env.MEMORIX_EMBEDDING_MODEL, toml.embedding?.model, yaml.embedding?.model, legacy.embeddingApi?.model),
|
|
2464
2467
|
baseUrl: embeddingBaseUrl,
|
|
2465
|
-
apiKey: first(process.env.MEMORIX_EMBEDDING_API_KEY, toml.embedding?.api_key, yaml.embedding?.apiKey, legacy.embeddingApi?.apiKey, openRouterEmbeddingApiKey),
|
|
2468
|
+
apiKey: first(process.env.MEMORIX_EMBEDDING_API_KEY, toml.embedding?.api_key, yaml.embedding?.apiKey, legacy.embeddingApi?.apiKey, openRouterEmbeddingApiKey, requestyEmbeddingApiKey),
|
|
2466
2469
|
dimensions: firstNumber(parseNumber(process.env.MEMORIX_EMBEDDING_DIMENSIONS), toml.embedding?.dimensions, yaml.embedding?.dimensions, legacy.embeddingApi?.dimensions)
|
|
2467
2470
|
},
|
|
2468
2471
|
rerank: resolveRerankLane({
|
|
@@ -2593,6 +2596,7 @@ function getEnvSourceNames() {
|
|
|
2593
2596
|
"MEMORIX_CODEGRAPH_EXTERNAL_COMMAND",
|
|
2594
2597
|
"MEMORIX_CODEGRAPH_EXTERNAL_TIMEOUT_MS",
|
|
2595
2598
|
"OPENROUTER_API_KEY",
|
|
2599
|
+
"REQUESTY_API_KEY",
|
|
2596
2600
|
"ATLASCLOUD_API_KEY"
|
|
2597
2601
|
].filter((name) => process.env[name]);
|
|
2598
2602
|
}
|
|
@@ -2605,6 +2609,15 @@ function isOpenRouterUrl(value) {
|
|
|
2605
2609
|
return /(^|\.)openrouter\.ai(?::|\/|$)/i.test(value);
|
|
2606
2610
|
}
|
|
2607
2611
|
}
|
|
2612
|
+
function isRequestyUrl(value) {
|
|
2613
|
+
if (!value) return false;
|
|
2614
|
+
try {
|
|
2615
|
+
const url = new URL(value);
|
|
2616
|
+
return url.hostname.toLowerCase() === "requesty.ai" || url.hostname.toLowerCase().endsWith(".requesty.ai");
|
|
2617
|
+
} catch {
|
|
2618
|
+
return /(^|\.)requesty\.ai(?::|\/|$)/i.test(value);
|
|
2619
|
+
}
|
|
2620
|
+
}
|
|
2608
2621
|
function isOpenRouterMemoryLane(provider2, baseUrl) {
|
|
2609
2622
|
return provider2?.trim().toLowerCase() === "openrouter" || isOpenRouterUrl(baseUrl);
|
|
2610
2623
|
}
|
|
@@ -2759,6 +2772,9 @@ function defaultEmbeddingModelFor(baseUrl, explicitModel) {
|
|
|
2759
2772
|
if (url && (url.hostname === "openrouter.ai" || url.hostname.endsWith(".openrouter.ai"))) {
|
|
2760
2773
|
return "qwen/qwen3-embedding-8b";
|
|
2761
2774
|
}
|
|
2775
|
+
if (url && (url.hostname === "requesty.ai" || url.hostname.endsWith(".requesty.ai"))) {
|
|
2776
|
+
return "openai/text-embedding-3-small";
|
|
2777
|
+
}
|
|
2762
2778
|
} catch {
|
|
2763
2779
|
}
|
|
2764
2780
|
return "text-embedding-3-small";
|
|
@@ -5573,6 +5589,7 @@ var init_provider2 = __esm({
|
|
|
5573
5589
|
openai: { baseUrl: "https://api.openai.com/v1", model: "gpt-4.1-nano" },
|
|
5574
5590
|
anthropic: { baseUrl: "https://api.anthropic.com/v1", model: "claude-3-5-haiku-latest" },
|
|
5575
5591
|
openrouter: { baseUrl: "https://openrouter.ai/api/v1", model: "openai/gpt-4.1-nano" },
|
|
5592
|
+
requesty: { baseUrl: "https://router.requesty.ai/v1", model: "openai/gpt-4.1-nano" },
|
|
5576
5593
|
atlascloud: { baseUrl: "https://api.atlascloud.ai/v1", model: "deepseek-ai/deepseek-v3.2" },
|
|
5577
5594
|
custom: { baseUrl: "http://localhost:11434/v1", model: "llama3" }
|
|
5578
5595
|
};
|
|
@@ -6,6 +6,23 @@ All notable changes to this project will be documented in this file.
|
|
|
6
6
|
|
|
7
7
|
No unreleased changes.
|
|
8
8
|
|
|
9
|
+
## [1.9.10] - 2026-10-08
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- **OpenCode 1.x regression** -- generated plugins now include the v1
|
|
13
|
+
`server` field alongside the v2 `setup` contract, so OpenCode 1.x can load
|
|
14
|
+
the legacy named export. Lifecycle, file, command, message, and compaction
|
|
15
|
+
events are also forwarded through the v1 generic `event` hook, with a longer
|
|
16
|
+
Windows hook timeout to reduce stale Bun timer failures.
|
|
17
|
+
|
|
18
|
+
## [1.9.9] - 2026-10-02
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- **Requesty memory preset** -- `memorix init` and the configuration TUI can
|
|
22
|
+
select Requesty for optional background memory LLM work through its
|
|
23
|
+
OpenAI-compatible endpoint, with provider-specific key isolation.
|
|
24
|
+
`REQUESTY_API_KEY` is also accepted for Requesty embedding endpoints.
|
|
25
|
+
|
|
9
26
|
## [1.9.8] - 2026-10-02
|
|
10
27
|
|
|
11
28
|
### Fixed
|
package/dist/sdk.js
CHANGED
|
@@ -3847,6 +3847,7 @@ function getResolvedConfig(options = {}) {
|
|
|
3847
3847
|
const legacy = loadFileConfig(homeDir);
|
|
3848
3848
|
const embeddingBaseUrl = first(process.env.MEMORIX_EMBEDDING_BASE_URL, toml.embedding?.base_url, yaml.embedding?.baseUrl, legacy.embeddingApi?.baseUrl);
|
|
3849
3849
|
const openRouterEmbeddingApiKey = isOpenRouterUrl(embeddingBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
3850
|
+
const requestyEmbeddingApiKey = isRequestyUrl(embeddingBaseUrl) ? process.env.REQUESTY_API_KEY : void 0;
|
|
3850
3851
|
const memoryLlmProvider = first(
|
|
3851
3852
|
process.env.MEMORIX_LLM_PROVIDER,
|
|
3852
3853
|
toml.memory?.llm?.provider,
|
|
@@ -3867,16 +3868,18 @@ function getResolvedConfig(options = {}) {
|
|
|
3867
3868
|
);
|
|
3868
3869
|
const openRouterMemoryLlmApiKey = isOpenRouterMemoryLane(memoryLlmProvider, memoryLlmBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
3869
3870
|
const isAtlasCloud = memoryLlmProvider === "atlascloud";
|
|
3871
|
+
const isRequesty = memoryLlmProvider === "requesty";
|
|
3872
|
+
const usesPresetKeyOnly = isAtlasCloud || isRequesty;
|
|
3870
3873
|
const memoryLlmApiKey = first(
|
|
3871
3874
|
process.env.MEMORIX_LLM_API_KEY,
|
|
3872
3875
|
process.env.MEMORIX_API_KEY,
|
|
3873
3876
|
toml.memory?.llm?.api_key,
|
|
3874
3877
|
yaml.llm?.apiKey,
|
|
3875
3878
|
legacy.llm?.apiKey,
|
|
3876
|
-
// Never borrow another provider's credentials for the Atlas Cloud
|
|
3877
|
-
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : process.env.OPENAI_API_KEY,
|
|
3878
|
-
|
|
3879
|
-
|
|
3879
|
+
// Never borrow another provider's credentials for the Atlas Cloud or Requesty presets.
|
|
3880
|
+
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : isRequesty ? process.env.REQUESTY_API_KEY : process.env.OPENAI_API_KEY,
|
|
3881
|
+
usesPresetKeyOnly ? void 0 : process.env.ANTHROPIC_API_KEY,
|
|
3882
|
+
usesPresetKeyOnly ? void 0 : openRouterMemoryLlmApiKey
|
|
3880
3883
|
);
|
|
3881
3884
|
const resolved = {
|
|
3882
3885
|
agent: {
|
|
@@ -3925,7 +3928,7 @@ function getResolvedConfig(options = {}) {
|
|
|
3925
3928
|
provider: first(process.env.MEMORIX_EMBEDDING, toml.embedding?.provider, yaml.embedding?.provider, legacy.embedding, "off"),
|
|
3926
3929
|
model: first(process.env.MEMORIX_EMBEDDING_MODEL, toml.embedding?.model, yaml.embedding?.model, legacy.embeddingApi?.model),
|
|
3927
3930
|
baseUrl: embeddingBaseUrl,
|
|
3928
|
-
apiKey: first(process.env.MEMORIX_EMBEDDING_API_KEY, toml.embedding?.api_key, yaml.embedding?.apiKey, legacy.embeddingApi?.apiKey, openRouterEmbeddingApiKey),
|
|
3931
|
+
apiKey: first(process.env.MEMORIX_EMBEDDING_API_KEY, toml.embedding?.api_key, yaml.embedding?.apiKey, legacy.embeddingApi?.apiKey, openRouterEmbeddingApiKey, requestyEmbeddingApiKey),
|
|
3929
3932
|
dimensions: firstNumber(parseNumber(process.env.MEMORIX_EMBEDDING_DIMENSIONS), toml.embedding?.dimensions, yaml.embedding?.dimensions, legacy.embeddingApi?.dimensions)
|
|
3930
3933
|
},
|
|
3931
3934
|
rerank: resolveRerankLane({
|
|
@@ -4056,6 +4059,7 @@ function getEnvSourceNames() {
|
|
|
4056
4059
|
"MEMORIX_CODEGRAPH_EXTERNAL_COMMAND",
|
|
4057
4060
|
"MEMORIX_CODEGRAPH_EXTERNAL_TIMEOUT_MS",
|
|
4058
4061
|
"OPENROUTER_API_KEY",
|
|
4062
|
+
"REQUESTY_API_KEY",
|
|
4059
4063
|
"ATLASCLOUD_API_KEY"
|
|
4060
4064
|
].filter((name) => process.env[name]);
|
|
4061
4065
|
}
|
|
@@ -4068,6 +4072,15 @@ function isOpenRouterUrl(value) {
|
|
|
4068
4072
|
return /(^|\.)openrouter\.ai(?::|\/|$)/i.test(value);
|
|
4069
4073
|
}
|
|
4070
4074
|
}
|
|
4075
|
+
function isRequestyUrl(value) {
|
|
4076
|
+
if (!value) return false;
|
|
4077
|
+
try {
|
|
4078
|
+
const url = new URL(value);
|
|
4079
|
+
return url.hostname.toLowerCase() === "requesty.ai" || url.hostname.toLowerCase().endsWith(".requesty.ai");
|
|
4080
|
+
} catch {
|
|
4081
|
+
return /(^|\.)requesty\.ai(?::|\/|$)/i.test(value);
|
|
4082
|
+
}
|
|
4083
|
+
}
|
|
4071
4084
|
function isOpenRouterMemoryLane(provider2, baseUrl) {
|
|
4072
4085
|
return provider2?.trim().toLowerCase() === "openrouter" || isOpenRouterUrl(baseUrl);
|
|
4073
4086
|
}
|
|
@@ -4222,6 +4235,9 @@ function defaultEmbeddingModelFor(baseUrl, explicitModel) {
|
|
|
4222
4235
|
if (url && (url.hostname === "openrouter.ai" || url.hostname.endsWith(".openrouter.ai"))) {
|
|
4223
4236
|
return "qwen/qwen3-embedding-8b";
|
|
4224
4237
|
}
|
|
4238
|
+
if (url && (url.hostname === "requesty.ai" || url.hostname.endsWith(".requesty.ai"))) {
|
|
4239
|
+
return "openai/text-embedding-3-small";
|
|
4240
|
+
}
|
|
4225
4241
|
} catch {
|
|
4226
4242
|
}
|
|
4227
4243
|
return "text-embedding-3-small";
|
|
@@ -7036,6 +7052,7 @@ var init_provider2 = __esm({
|
|
|
7036
7052
|
openai: { baseUrl: "https://api.openai.com/v1", model: "gpt-4.1-nano" },
|
|
7037
7053
|
anthropic: { baseUrl: "https://api.anthropic.com/v1", model: "claude-3-5-haiku-latest" },
|
|
7038
7054
|
openrouter: { baseUrl: "https://openrouter.ai/api/v1", model: "openai/gpt-4.1-nano" },
|
|
7055
|
+
requesty: { baseUrl: "https://router.requesty.ai/v1", model: "openai/gpt-4.1-nano" },
|
|
7039
7056
|
atlascloud: { baseUrl: "https://api.atlascloud.ai/v1", model: "deepseek-ai/deepseek-v3.2" },
|
|
7040
7057
|
custom: { baseUrl: "http://localhost:11434/v1", model: "llama3" }
|
|
7041
7058
|
};
|
|
@@ -163566,7 +163583,8 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
163566
163583
|
"MEMORIX_API_KEY",
|
|
163567
163584
|
"OPENAI_API_KEY",
|
|
163568
163585
|
"ANTHROPIC_API_KEY",
|
|
163569
|
-
...resolved.memory.llm.provider === "openrouter" || resolved.memory.llm.baseUrl?.includes("openrouter.ai") ? ["OPENROUTER_API_KEY"] : []
|
|
163586
|
+
...resolved.memory.llm.provider === "openrouter" || resolved.memory.llm.baseUrl?.includes("openrouter.ai") ? ["OPENROUTER_API_KEY"] : [],
|
|
163587
|
+
...resolved.memory.llm.provider === "requesty" ? ["REQUESTY_API_KEY"] : []
|
|
163570
163588
|
];
|
|
163571
163589
|
if (llmKey) {
|
|
163572
163590
|
const src = resolveDashboardKeySource({ value: llmKey, envKeys: memoryKeyEnv, configSource });
|
|
@@ -165151,7 +165169,7 @@ async function analyzeImage(input) {
|
|
|
165151
165169
|
const config = getLLMConfig();
|
|
165152
165170
|
if (!OPENAI_COMPATIBLE_PROVIDERS.has(config.provider)) {
|
|
165153
165171
|
throw new Error(
|
|
165154
|
-
`Image analysis requires an OpenAI-compatible provider (openai, openrouter, or custom). Current provider "${config.provider}" uses a different API shape. Set MEMORIX_LLM_PROVIDER=openai or configure an OpenAI-compatible base URL.`
|
|
165172
|
+
`Image analysis requires an OpenAI-compatible provider (openai, openrouter, requesty, or custom). Current provider "${config.provider}" uses a different API shape. Set MEMORIX_LLM_PROVIDER=openai or configure an OpenAI-compatible base URL.`
|
|
165155
165173
|
);
|
|
165156
165174
|
}
|
|
165157
165175
|
const bytes = decodeBase64ImagePayload(input.base64, MAX_VISION_IMAGE_BYTES);
|
|
@@ -165190,7 +165208,7 @@ var init_image_loader = __esm({
|
|
|
165190
165208
|
init_provider2();
|
|
165191
165209
|
init_secret_filter();
|
|
165192
165210
|
init_image_payload();
|
|
165193
|
-
OPENAI_COMPATIBLE_PROVIDERS = /* @__PURE__ */ new Set(["openai", "openrouter", "custom"]);
|
|
165211
|
+
OPENAI_COMPATIBLE_PROVIDERS = /* @__PURE__ */ new Set(["openai", "openrouter", "requesty", "custom"]);
|
|
165194
165212
|
MAX_VISION_PROMPT_CHARS = 12e3;
|
|
165195
165213
|
MAX_VISION_DESCRIPTION_CHARS = 12e3;
|
|
165196
165214
|
MAX_VISION_LABELS = 50;
|
|
@@ -165905,6 +165923,8 @@ function generateOpenCodePlugin() {
|
|
|
165905
165923
|
*/
|
|
165906
165924
|
import { spawnSync } from 'node:child_process';
|
|
165907
165925
|
|
|
165926
|
+
const HOOK_TIMEOUT_MS = 30_000;
|
|
165927
|
+
|
|
165908
165928
|
export const MemorixPlugin = async ({ project, client, $, directory, worktree }) => {
|
|
165909
165929
|
// Generate a stable session ID for this plugin lifetime
|
|
165910
165930
|
const sessionId = \`opencode-\${Date.now().toString(36)}-\${Math.random().toString(36).slice(2, 8)}\`;
|
|
@@ -165930,14 +165950,14 @@ export const MemorixPlugin = async ({ project, client, $, directory, worktree })
|
|
|
165930
165950
|
* - spawnSync is simpler: no stream lifecycle, no writer.close() bugs
|
|
165931
165951
|
* - stdin pipe via input option is reliable cross-platform
|
|
165932
165952
|
*/
|
|
165933
|
-
function runHook(payload) {
|
|
165934
|
-
payload.session_id =
|
|
165953
|
+
function runHook(payload, activeSessionId = sessionId) {
|
|
165954
|
+
payload.session_id = activeSessionId;
|
|
165935
165955
|
const data = JSON.stringify(payload);
|
|
165936
165956
|
const eventName = payload.hook_event_name || 'unknown';
|
|
165937
165957
|
try {
|
|
165938
165958
|
const result = spawnSync(hookCommand, ['hook'], {
|
|
165939
165959
|
input: data,
|
|
165940
|
-
timeout:
|
|
165960
|
+
timeout: HOOK_TIMEOUT_MS,
|
|
165941
165961
|
encoding: 'utf-8',
|
|
165942
165962
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
165943
165963
|
shell: process.platform === 'win32',
|
|
@@ -165982,7 +166002,87 @@ export const MemorixPlugin = async ({ project, client, $, directory, worktree })
|
|
|
165982
166002
|
.trim();
|
|
165983
166003
|
}
|
|
165984
166004
|
|
|
166005
|
+
function flushAssistantResponse(activeSessionId = sessionId) {
|
|
166006
|
+
if (!pendingAssistantResponse?.text) return;
|
|
166007
|
+
const deliveryKey = pendingAssistantResponse.id
|
|
166008
|
+
? \`\${pendingAssistantResponse.id}:\${pendingAssistantResponse.text}\`
|
|
166009
|
+
: pendingAssistantResponse.text;
|
|
166010
|
+
if (deliveryKey === lastDeliveredAssistantKey) return;
|
|
166011
|
+
runHook({
|
|
166012
|
+
agent: 'opencode',
|
|
166013
|
+
hook_event_name: 'message.updated',
|
|
166014
|
+
ai_response: pendingAssistantResponse.text,
|
|
166015
|
+
message_id: pendingAssistantResponse.id,
|
|
166016
|
+
cwd: directory,
|
|
166017
|
+
}, activeSessionId);
|
|
166018
|
+
lastDeliveredAssistantKey = deliveryKey;
|
|
166019
|
+
}
|
|
166020
|
+
|
|
166021
|
+
function eventSessionId(event) {
|
|
166022
|
+
const properties = event?.properties ?? {};
|
|
166023
|
+
const value = properties.sessionID ?? properties.sessionId ?? properties.info?.id;
|
|
166024
|
+
return typeof value === 'string' && value ? value : sessionId;
|
|
166025
|
+
}
|
|
166026
|
+
|
|
166027
|
+
async function handleEvent({ event }) {
|
|
166028
|
+
const properties = event?.properties ?? {};
|
|
166029
|
+
const activeSessionId = eventSessionId(event);
|
|
166030
|
+
switch (event?.type) {
|
|
166031
|
+
case 'session.created':
|
|
166032
|
+
runHook({
|
|
166033
|
+
agent: 'opencode',
|
|
166034
|
+
hook_event_name: 'session.created',
|
|
166035
|
+
cwd: directory,
|
|
166036
|
+
}, activeSessionId);
|
|
166037
|
+
break;
|
|
166038
|
+
case 'session.idle':
|
|
166039
|
+
flushAssistantResponse(activeSessionId);
|
|
166040
|
+
runHook({
|
|
166041
|
+
agent: 'opencode',
|
|
166042
|
+
hook_event_name: 'session.idle',
|
|
166043
|
+
cwd: directory,
|
|
166044
|
+
}, activeSessionId);
|
|
166045
|
+
break;
|
|
166046
|
+
case 'file.edited':
|
|
166047
|
+
runHook({
|
|
166048
|
+
agent: 'opencode',
|
|
166049
|
+
hook_event_name: 'file.edited',
|
|
166050
|
+
file_path: properties.file ?? properties.path ?? '',
|
|
166051
|
+
cwd: directory,
|
|
166052
|
+
}, activeSessionId);
|
|
166053
|
+
break;
|
|
166054
|
+
case 'command.executed':
|
|
166055
|
+
runHook({
|
|
166056
|
+
agent: 'opencode',
|
|
166057
|
+
hook_event_name: 'command.executed',
|
|
166058
|
+
command: properties.name ?? properties.command ?? '',
|
|
166059
|
+
cwd: directory,
|
|
166060
|
+
}, activeSessionId);
|
|
166061
|
+
break;
|
|
166062
|
+
case 'message.updated': {
|
|
166063
|
+
const message = properties.info ?? properties.message ?? properties;
|
|
166064
|
+
if (message?.role !== 'assistant') break;
|
|
166065
|
+
const text = extractMessageText(message);
|
|
166066
|
+
if (!text) break;
|
|
166067
|
+
pendingAssistantResponse = { id: message.id, text };
|
|
166068
|
+
break;
|
|
166069
|
+
}
|
|
166070
|
+
case 'session.compacted':
|
|
166071
|
+
runHook({
|
|
166072
|
+
agent: 'opencode',
|
|
166073
|
+
hook_event_name: 'session.compacted',
|
|
166074
|
+
cwd: directory,
|
|
166075
|
+
}, activeSessionId);
|
|
166076
|
+
break;
|
|
166077
|
+
default:
|
|
166078
|
+
break;
|
|
166079
|
+
}
|
|
166080
|
+
}
|
|
166081
|
+
|
|
165985
166082
|
return {
|
|
166083
|
+
// OpenCode 1.x delivers lifecycle/file/command/message events through this
|
|
166084
|
+
// generic hook. The named keys below remain for older compatible hosts.
|
|
166085
|
+
event: handleEvent,
|
|
165986
166086
|
/** Session created \u2014 record session start */
|
|
165987
166087
|
'session.created': async ({ session }) => {
|
|
165988
166088
|
runHook({
|
|
@@ -165994,21 +166094,7 @@ export const MemorixPlugin = async ({ project, client, $, directory, worktree })
|
|
|
165994
166094
|
|
|
165995
166095
|
/** Session idle \u2014 record session end */
|
|
165996
166096
|
'session.idle': async ({ session }) => {
|
|
165997
|
-
|
|
165998
|
-
const deliveryKey = pendingAssistantResponse.id
|
|
165999
|
-
? \`\${pendingAssistantResponse.id}:\${pendingAssistantResponse.text}\`
|
|
166000
|
-
: pendingAssistantResponse.text;
|
|
166001
|
-
if (deliveryKey !== lastDeliveredAssistantKey) {
|
|
166002
|
-
runHook({
|
|
166003
|
-
agent: 'opencode',
|
|
166004
|
-
hook_event_name: 'message.updated',
|
|
166005
|
-
ai_response: pendingAssistantResponse.text,
|
|
166006
|
-
message_id: pendingAssistantResponse.id,
|
|
166007
|
-
cwd: directory,
|
|
166008
|
-
});
|
|
166009
|
-
lastDeliveredAssistantKey = deliveryKey;
|
|
166010
|
-
}
|
|
166011
|
-
}
|
|
166097
|
+
flushAssistantResponse();
|
|
166012
166098
|
runHook({
|
|
166013
166099
|
agent: 'opencode',
|
|
166014
166100
|
hook_event_name: 'session.idle',
|
|
@@ -166116,7 +166202,7 @@ function v2RunHook(payload, directory, sessionId) {
|
|
|
166116
166202
|
try {
|
|
166117
166203
|
const result = spawnSync(v2HookCommand, ['hook'], {
|
|
166118
166204
|
input: JSON.stringify(nextPayload),
|
|
166119
|
-
timeout:
|
|
166205
|
+
timeout: HOOK_TIMEOUT_MS,
|
|
166120
166206
|
encoding: 'utf-8',
|
|
166121
166207
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
166122
166208
|
shell: process.platform === 'win32',
|
|
@@ -166240,7 +166326,7 @@ function setup(ctx) {
|
|
|
166240
166326
|
return () => controller.abort();
|
|
166241
166327
|
}
|
|
166242
166328
|
|
|
166243
|
-
export default { id: 'memorix', setup };
|
|
166329
|
+
export default { id: 'memorix', server: MemorixPlugin, setup };
|
|
166244
166330
|
`;
|
|
166245
166331
|
}
|
|
166246
166332
|
async function installOpenCodeSkills(projectRoot, global2 = false) {
|
|
@@ -167066,7 +167152,7 @@ var init_installers = __esm({
|
|
|
167066
167152
|
"use strict";
|
|
167067
167153
|
init_esm_shims();
|
|
167068
167154
|
init_official_skills();
|
|
167069
|
-
OPENCODE_PLUGIN_VERSION =
|
|
167155
|
+
OPENCODE_PLUGIN_VERSION = 9;
|
|
167070
167156
|
AGENT_SKILL_DIRS = {
|
|
167071
167157
|
cursor: { project: path34.join(".cursor", "skills"), global: path34.join(".cursor", "skills") },
|
|
167072
167158
|
windsurf: { project: path34.join(".windsurf", "skills"), global: path34.join(".windsurf", "skills") },
|
|
@@ -170971,7 +171057,7 @@ var MCP_SERVER_INFO_META_KEY = "io.modelcontextprotocol/serverInfo";
|
|
|
170971
171057
|
function getMcpServerInfo() {
|
|
170972
171058
|
return {
|
|
170973
171059
|
name: "memorix",
|
|
170974
|
-
version: true ? "1.9.
|
|
171060
|
+
version: true ? "1.9.10" : "1.0.1"
|
|
170975
171061
|
};
|
|
170976
171062
|
}
|
|
170977
171063
|
function createMcpDiscoverResult(capabilities, serverInfo) {
|
|
@@ -2384,6 +2384,7 @@ function getResolvedConfig(options = {}) {
|
|
|
2384
2384
|
const legacy = loadFileConfig(homeDir);
|
|
2385
2385
|
const embeddingBaseUrl = first(process.env.MEMORIX_EMBEDDING_BASE_URL, toml.embedding?.base_url, yaml.embedding?.baseUrl, legacy.embeddingApi?.baseUrl);
|
|
2386
2386
|
const openRouterEmbeddingApiKey = isOpenRouterUrl(embeddingBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
2387
|
+
const requestyEmbeddingApiKey = isRequestyUrl(embeddingBaseUrl) ? process.env.REQUESTY_API_KEY : void 0;
|
|
2387
2388
|
const memoryLlmProvider = first(
|
|
2388
2389
|
process.env.MEMORIX_LLM_PROVIDER,
|
|
2389
2390
|
toml.memory?.llm?.provider,
|
|
@@ -2404,16 +2405,18 @@ function getResolvedConfig(options = {}) {
|
|
|
2404
2405
|
);
|
|
2405
2406
|
const openRouterMemoryLlmApiKey = isOpenRouterMemoryLane(memoryLlmProvider, memoryLlmBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
2406
2407
|
const isAtlasCloud = memoryLlmProvider === "atlascloud";
|
|
2408
|
+
const isRequesty = memoryLlmProvider === "requesty";
|
|
2409
|
+
const usesPresetKeyOnly = isAtlasCloud || isRequesty;
|
|
2407
2410
|
const memoryLlmApiKey = first(
|
|
2408
2411
|
process.env.MEMORIX_LLM_API_KEY,
|
|
2409
2412
|
process.env.MEMORIX_API_KEY,
|
|
2410
2413
|
toml.memory?.llm?.api_key,
|
|
2411
2414
|
yaml.llm?.apiKey,
|
|
2412
2415
|
legacy.llm?.apiKey,
|
|
2413
|
-
// Never borrow another provider's credentials for the Atlas Cloud
|
|
2414
|
-
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : process.env.OPENAI_API_KEY,
|
|
2415
|
-
|
|
2416
|
-
|
|
2416
|
+
// Never borrow another provider's credentials for the Atlas Cloud or Requesty presets.
|
|
2417
|
+
isAtlasCloud ? process.env.ATLASCLOUD_API_KEY : isRequesty ? process.env.REQUESTY_API_KEY : process.env.OPENAI_API_KEY,
|
|
2418
|
+
usesPresetKeyOnly ? void 0 : process.env.ANTHROPIC_API_KEY,
|
|
2419
|
+
usesPresetKeyOnly ? void 0 : openRouterMemoryLlmApiKey
|
|
2417
2420
|
);
|
|
2418
2421
|
const resolved = {
|
|
2419
2422
|
agent: {
|
|
@@ -2462,7 +2465,7 @@ function getResolvedConfig(options = {}) {
|
|
|
2462
2465
|
provider: first(process.env.MEMORIX_EMBEDDING, toml.embedding?.provider, yaml.embedding?.provider, legacy.embedding, "off"),
|
|
2463
2466
|
model: first(process.env.MEMORIX_EMBEDDING_MODEL, toml.embedding?.model, yaml.embedding?.model, legacy.embeddingApi?.model),
|
|
2464
2467
|
baseUrl: embeddingBaseUrl,
|
|
2465
|
-
apiKey: first(process.env.MEMORIX_EMBEDDING_API_KEY, toml.embedding?.api_key, yaml.embedding?.apiKey, legacy.embeddingApi?.apiKey, openRouterEmbeddingApiKey),
|
|
2468
|
+
apiKey: first(process.env.MEMORIX_EMBEDDING_API_KEY, toml.embedding?.api_key, yaml.embedding?.apiKey, legacy.embeddingApi?.apiKey, openRouterEmbeddingApiKey, requestyEmbeddingApiKey),
|
|
2466
2469
|
dimensions: firstNumber(parseNumber(process.env.MEMORIX_EMBEDDING_DIMENSIONS), toml.embedding?.dimensions, yaml.embedding?.dimensions, legacy.embeddingApi?.dimensions)
|
|
2467
2470
|
},
|
|
2468
2471
|
rerank: resolveRerankLane({
|
|
@@ -2593,6 +2596,7 @@ function getEnvSourceNames() {
|
|
|
2593
2596
|
"MEMORIX_CODEGRAPH_EXTERNAL_COMMAND",
|
|
2594
2597
|
"MEMORIX_CODEGRAPH_EXTERNAL_TIMEOUT_MS",
|
|
2595
2598
|
"OPENROUTER_API_KEY",
|
|
2599
|
+
"REQUESTY_API_KEY",
|
|
2596
2600
|
"ATLASCLOUD_API_KEY"
|
|
2597
2601
|
].filter((name) => process.env[name]);
|
|
2598
2602
|
}
|
|
@@ -2605,6 +2609,15 @@ function isOpenRouterUrl(value) {
|
|
|
2605
2609
|
return /(^|\.)openrouter\.ai(?::|\/|$)/i.test(value);
|
|
2606
2610
|
}
|
|
2607
2611
|
}
|
|
2612
|
+
function isRequestyUrl(value) {
|
|
2613
|
+
if (!value) return false;
|
|
2614
|
+
try {
|
|
2615
|
+
const url = new URL(value);
|
|
2616
|
+
return url.hostname.toLowerCase() === "requesty.ai" || url.hostname.toLowerCase().endsWith(".requesty.ai");
|
|
2617
|
+
} catch {
|
|
2618
|
+
return /(^|\.)requesty\.ai(?::|\/|$)/i.test(value);
|
|
2619
|
+
}
|
|
2620
|
+
}
|
|
2608
2621
|
function isOpenRouterMemoryLane(provider2, baseUrl) {
|
|
2609
2622
|
return provider2?.trim().toLowerCase() === "openrouter" || isOpenRouterUrl(baseUrl);
|
|
2610
2623
|
}
|
|
@@ -2759,6 +2772,9 @@ function defaultEmbeddingModelFor(baseUrl, explicitModel) {
|
|
|
2759
2772
|
if (url && (url.hostname === "openrouter.ai" || url.hostname.endsWith(".openrouter.ai"))) {
|
|
2760
2773
|
return "qwen/qwen3-embedding-8b";
|
|
2761
2774
|
}
|
|
2775
|
+
if (url && (url.hostname === "requesty.ai" || url.hostname.endsWith(".requesty.ai"))) {
|
|
2776
|
+
return "openai/text-embedding-3-small";
|
|
2777
|
+
}
|
|
2762
2778
|
} catch {
|
|
2763
2779
|
}
|
|
2764
2780
|
return "text-embedding-3-small";
|
|
@@ -5573,6 +5589,7 @@ var init_provider2 = __esm({
|
|
|
5573
5589
|
openai: { baseUrl: "https://api.openai.com/v1", model: "gpt-4.1-nano" },
|
|
5574
5590
|
anthropic: { baseUrl: "https://api.anthropic.com/v1", model: "claude-3-5-haiku-latest" },
|
|
5575
5591
|
openrouter: { baseUrl: "https://openrouter.ai/api/v1", model: "openai/gpt-4.1-nano" },
|
|
5592
|
+
requesty: { baseUrl: "https://router.requesty.ai/v1", model: "openai/gpt-4.1-nano" },
|
|
5576
5593
|
atlascloud: { baseUrl: "https://api.atlascloud.ai/v1", model: "deepseek-ai/deepseek-v3.2" },
|
|
5577
5594
|
custom: { baseUrl: "http://localhost:11434/v1", model: "llama3" }
|
|
5578
5595
|
};
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -178,6 +178,23 @@ This is opt-in background memory processing and may incur API charges. Setting
|
|
|
178
178
|
`ATLASCLOUD_API_KEY` alone does not enable it. Embeddings and memcode's model
|
|
179
179
|
registry are unchanged.
|
|
180
180
|
|
|
181
|
+
Requesty is available as a memory LLM preset in `memorix init` and the
|
|
182
|
+
configuration TUI:
|
|
183
|
+
|
|
184
|
+
```toml
|
|
185
|
+
[memory.llm]
|
|
186
|
+
provider = "requesty"
|
|
187
|
+
model = "openai/gpt-4o-mini"
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The preset uses `https://router.requesty.ai/v1` and the existing
|
|
191
|
+
OpenAI-compatible chat completion transport. Set `REQUESTY_API_KEY` or
|
|
192
|
+
`MEMORIX_LLM_API_KEY`; the preset does not fall back to OpenAI, Anthropic, or
|
|
193
|
+
OpenRouter environment keys. Model IDs use the `vendor/model` form, for example
|
|
194
|
+
`anthropic/claude-sonnet-4-5`. To keep traffic in the EU, set
|
|
195
|
+
`base_url = "https://router.eu.requesty.ai/v1"`. Get a key at
|
|
196
|
+
https://app.requesty.ai/api-keys.
|
|
197
|
+
|
|
181
198
|
OrcaRouter works through the generic OpenAI-compatible gateway path. Keep the
|
|
182
199
|
provider label as `openai`, set its base URL, and use an explicit model ID:
|
|
183
200
|
|
|
@@ -247,6 +264,11 @@ OpenAI-only default. The equivalent env-var form is
|
|
|
247
264
|
`MEMORIX_EMBEDDING=api`, `MEMORIX_EMBEDDING_BASE_URL=https://openrouter.ai/api/v1`,
|
|
248
265
|
`MEMORIX_EMBEDDING_MODEL=qwen/qwen3-embedding-8b`.
|
|
249
266
|
|
|
267
|
+
Requesty embeddings work the same way with
|
|
268
|
+
`base_url = "https://router.requesty.ai/v1"`. Memorix then accepts
|
|
269
|
+
`REQUESTY_API_KEY` for the embedding endpoint and, when no `model` is
|
|
270
|
+
configured, defaults to `openai/text-embedding-3-small`.
|
|
271
|
+
|
|
250
272
|
### Large-store retrieval
|
|
251
273
|
|
|
252
274
|
Memorix does not cap the number of durable observations to make search fast.
|