memorix 1.6.0 → 1.6.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/CHANGELOG.md +24 -0
- package/TEAM.md +86 -86
- package/dist/cli/index.js +317 -62
- package/dist/cli/memcode.js +12 -1
- package/dist/index.js +56 -9
- package/dist/maintenance-runner.js +54 -7
- package/dist/media-audio-runner.js +54 -7
- package/dist/media-video-runner.js +54 -7
- package/dist/memcode-runtime/CHANGELOG.md +24 -0
- package/dist/sdk.js +55 -8
- package/dist/vector-backfill-runner.js +54 -7
- package/docs/AGENT_OPERATOR_PLAYBOOK.md +11 -3
- package/docs/API_REFERENCE.md +1 -1
- package/docs/DESIGN_DECISIONS.md +357 -357
- package/docs/DOCKER.md +5 -1
- package/docs/PERFORMANCE.md +2 -2
- package/docs/README.md +3 -1
- package/docs/SETUP.md +8 -2
- package/package.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/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/audit/index.ts +156 -156
- package/src/cli/commands/agent-integrations.ts +9 -3
- package/src/cli/commands/doctor.ts +46 -15
- package/src/cli/commands/formation.ts +48 -48
- package/src/cli/commands/git-hook-install.ts +111 -111
- package/src/cli/commands/handoff.ts +54 -54
- package/src/cli/commands/hook.ts +13 -1
- package/src/cli/commands/hooks-status.ts +63 -63
- package/src/cli/commands/ingest.ts +44 -44
- package/src/cli/commands/integrate-shared.ts +15 -15
- package/src/cli/commands/lock.ts +82 -82
- package/src/cli/commands/message.ts +104 -104
- package/src/cli/commands/poll.ts +58 -58
- package/src/cli/commands/reasoning.ts +118 -118
- package/src/cli/commands/serve-http.ts +68 -7
- package/src/cli/commands/skills.ts +114 -114
- package/src/cli/commands/task.ts +167 -167
- package/src/cli/commands/transfer.ts +47 -47
- package/src/cli/heap.ts +76 -0
- package/src/cli/index.ts +406 -406
- package/src/cli/invocation.ts +7 -4
- package/src/cli/tui/ChatView.tsx +234 -234
- package/src/cli/tui/CommandBar.tsx +312 -312
- package/src/cli/tui/ContextRail.tsx +118 -118
- package/src/cli/tui/HeaderBar.tsx +72 -72
- package/src/cli/tui/LogoBanner.tsx +51 -51
- package/src/cli/tui/index.ts +41 -41
- package/src/cli/version.ts +7 -7
- package/src/cli/workbench.ts +1 -1
- package/src/dashboard/project-classification.ts +64 -64
- package/src/embedding/provider.ts +76 -6
- package/src/git/hooks-path.ts +85 -85
- package/src/hooks/handler.ts +9 -18
- package/src/hooks/lifecycle.ts +173 -0
- package/src/hooks/pattern-detector.ts +173 -173
- package/src/hooks/significance-filter.ts +250 -250
- package/src/llm/memory-manager.ts +328 -328
- package/src/llm/quality.ts +248 -248
- package/src/memory/attribution-guard.ts +249 -249
- package/src/memory/disclosure-policy.ts +135 -135
- package/src/memory/entity-extractor.ts +197 -197
- package/src/memory/formation/evaluate.ts +217 -217
- package/src/memory/freshness.ts +122 -122
- package/src/memory/graph.ts +197 -197
- package/src/memory/refs.ts +94 -94
- package/src/memory/secret-filter.ts +79 -79
- package/src/orchestrate/adapters/claude-stream.ts +192 -192
- package/src/orchestrate/adapters/claude.ts +111 -111
- package/src/orchestrate/adapters/codex-stream.ts +134 -134
- package/src/orchestrate/adapters/codex.ts +41 -41
- package/src/orchestrate/adapters/gemini-stream.ts +166 -166
- package/src/orchestrate/adapters/gemini.ts +42 -42
- package/src/orchestrate/adapters/index.ts +73 -73
- package/src/orchestrate/adapters/opencode-stream.ts +143 -143
- package/src/orchestrate/adapters/opencode.ts +47 -47
- package/src/orchestrate/adapters/types.ts +77 -77
- package/src/orchestrate/capability-router.ts +284 -284
- package/src/orchestrate/cost-tracker.ts +219 -219
- package/src/orchestrate/error-recovery.ts +191 -191
- package/src/orchestrate/evidence.ts +140 -140
- package/src/orchestrate/ledger.ts +110 -110
- package/src/orchestrate/memorix-bridge.ts +343 -343
- package/src/orchestrate/output-budget.ts +80 -80
- package/src/orchestrate/permission.ts +152 -152
- package/src/orchestrate/pipeline-trace.ts +131 -131
- package/src/orchestrate/prompt-builder.ts +155 -155
- package/src/orchestrate/ring-buffer.ts +37 -37
- package/src/orchestrate/task-graph.ts +389 -389
- package/src/project/aliases.ts +374 -374
- package/src/rules/adapters/trae.ts +56 -56
- package/src/rules/syncer.ts +235 -235
- package/src/search/query-expansion.ts +52 -52
- package/src/server/formation-timeout.ts +27 -27
- package/src/skills/mini-skills.ts +386 -386
- package/src/store/chat-store.ts +119 -119
- package/src/store/graph-store.ts +249 -249
- package/src/store/mini-skill-store.ts +349 -349
- package/src/store/persistence-json.ts +212 -212
- package/src/store/persistence.ts +291 -291
- package/src/store/project-affinity.ts +195 -195
- package/src/team/event-bus.ts +76 -76
- package/src/team/handoff.ts +161 -161
- package/src/team/poll.ts +132 -132
- package/src/workspace/mcp-adapters/codex.ts +191 -191
- package/src/workspace/mcp-adapters/copilot.ts +105 -105
- package/src/workspace/mcp-adapters/cursor.ts +53 -53
- package/src/workspace/mcp-adapters/kiro.ts +64 -64
- package/src/workspace/mcp-adapters/opencode.ts +123 -123
- package/src/workspace/mcp-adapters/trae.ts +134 -134
- package/src/workspace/mcp-adapters/windsurf.ts +91 -91
- package/src/workspace/sanitizer.ts +60 -60
package/dist/cli/memcode.js
CHANGED
|
@@ -2,7 +2,18 @@
|
|
|
2
2
|
import {spawnSync as __ms} from "node:child_process";
|
|
3
3
|
import {fileURLToPath as __fu} from "node:url";
|
|
4
4
|
if(!process.env.__MEMORIX_HEAP){process.env.__MEMORIX_HEAP="1";
|
|
5
|
-
|
|
5
|
+
const __args=process.argv.slice(2);
|
|
6
|
+
let __cmd;
|
|
7
|
+
for(let __i=0;__i<__args.length;__i++){
|
|
8
|
+
const __a=__args[__i];
|
|
9
|
+
if(__a==="--")break;
|
|
10
|
+
if(__a.startsWith("-")){if(!__a.includes("=")&&__args[__i+1]&&!__args[__i+1].startsWith("-"))__i++;continue;}
|
|
11
|
+
__cmd=__a;break;}
|
|
12
|
+
const __fallback=__cmd==="hook"?512:4096;
|
|
13
|
+
const __raw=__cmd==="hook"?process.env.MEMORIX_HOOK_HEAP_MB:process.env.MEMORIX_HEAP_MB;
|
|
14
|
+
const __n=Number(__raw);
|
|
15
|
+
const __heap=(Number.isFinite(__n)&&__n>=64&&__n<=16384)?String(Math.floor(__n)):String(__fallback);
|
|
16
|
+
let r=__ms(process.execPath,["--max-old-space-size="+__heap,__fu(import.meta.url),...process.argv.slice(2)],{stdio:"inherit",env:process.env,windowsHide:true});
|
|
6
17
|
process.exit(r.status??1);}
|
|
7
18
|
import {createRequire as __memorix_cjsRequire} from "module";
|
|
8
19
|
const require = __memorix_cjsRequire(import.meta.url);
|
package/dist/index.js
CHANGED
|
@@ -4438,6 +4438,7 @@ __export(provider_exports, {
|
|
|
4438
4438
|
MAX_INLINE_EMBEDDING_BYTES: () => MAX_INLINE_EMBEDDING_BYTES,
|
|
4439
4439
|
UnsupportedEmbeddingModalityError: () => UnsupportedEmbeddingModalityError,
|
|
4440
4440
|
getEmbeddingProvider: () => getEmbeddingProvider,
|
|
4441
|
+
getEmbeddingRuntimeHealth: () => getEmbeddingRuntimeHealth,
|
|
4441
4442
|
isEmbeddingExplicitlyDisabled: () => isEmbeddingExplicitlyDisabled,
|
|
4442
4443
|
isVectorSearchAvailable: () => isVectorSearchAvailable,
|
|
4443
4444
|
resetProvider: () => resetProvider,
|
|
@@ -4545,13 +4546,36 @@ function isTemporaryEmbeddingFailure(error) {
|
|
|
4545
4546
|
if (!(error instanceof Error)) return false;
|
|
4546
4547
|
return /embedding api error \(401\)/i.test(error.message) || /invalid_api_key/i.test(error.message) || /incorrect api key/i.test(error.message) || /unauthorized/i.test(error.message) || /embedding api timeout/i.test(error.message) || /embedding api error \((402|429|5\d\d)\)/i.test(error.message) || /quota exceeded/i.test(error.message) || /account balance/i.test(error.message) || /fetch failed/i.test(error.message) || /econnreset/i.test(error.message) || /econnrefused/i.test(error.message) || /temporarily unavailable/i.test(error.message);
|
|
4547
4548
|
}
|
|
4549
|
+
function classifyEmbeddingFailure(error) {
|
|
4550
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4551
|
+
if (/embedding api error \(401\)|invalid_api_key|incorrect api key|unauthorized/i.test(message)) {
|
|
4552
|
+
return "authorization";
|
|
4553
|
+
}
|
|
4554
|
+
if (/embedding api error \(402\)|quota exceeded|account balance/i.test(message)) {
|
|
4555
|
+
return "billing";
|
|
4556
|
+
}
|
|
4557
|
+
if (/embedding api timeout|abort/i.test(message)) {
|
|
4558
|
+
return "timeout";
|
|
4559
|
+
}
|
|
4560
|
+
return "upstream";
|
|
4561
|
+
}
|
|
4548
4562
|
function markTemporaryFailure(reason) {
|
|
4549
4563
|
provider = null;
|
|
4550
4564
|
initPromise = null;
|
|
4551
4565
|
lastInitWasTemporaryFailure = true;
|
|
4552
4566
|
lastFailureTimestamp = Date.now();
|
|
4567
|
+
lastEmbeddingFailure = {
|
|
4568
|
+
kind: classifyEmbeddingFailure(reason),
|
|
4569
|
+
occurredAt: lastFailureTimestamp
|
|
4570
|
+
};
|
|
4553
4571
|
const message = reason instanceof Error ? reason.message : String(reason);
|
|
4554
|
-
warnOnce(`[memorix] Embedding provider
|
|
4572
|
+
warnOnce(`[memorix] Embedding provider unavailable at runtime: ${message}`);
|
|
4573
|
+
}
|
|
4574
|
+
function markProviderReady(candidate) {
|
|
4575
|
+
provider = wrapProvider(candidate);
|
|
4576
|
+
lastInitWasTemporaryFailure = false;
|
|
4577
|
+
lastEmbeddingFailure = null;
|
|
4578
|
+
return provider;
|
|
4555
4579
|
}
|
|
4556
4580
|
async function createFastEmbedProvider() {
|
|
4557
4581
|
try {
|
|
@@ -4667,35 +4691,35 @@ async function getEmbeddingProvider(options = {}) {
|
|
|
4667
4691
|
if (mode === "fastembed") {
|
|
4668
4692
|
const initialized = await createFastEmbedProvider();
|
|
4669
4693
|
if (!initialized) return null;
|
|
4670
|
-
provider =
|
|
4694
|
+
provider = markProviderReady(initialized);
|
|
4671
4695
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4672
4696
|
return provider;
|
|
4673
4697
|
}
|
|
4674
4698
|
if (mode === "transformers") {
|
|
4675
4699
|
const initialized = await createTransformersProvider();
|
|
4676
4700
|
if (!initialized) return null;
|
|
4677
|
-
provider =
|
|
4701
|
+
provider = markProviderReady(initialized);
|
|
4678
4702
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4679
4703
|
return provider;
|
|
4680
4704
|
}
|
|
4681
4705
|
if (mode === "api") {
|
|
4682
4706
|
const initialized = await createAPIProvider(options);
|
|
4683
4707
|
if (!initialized) return null;
|
|
4684
|
-
provider =
|
|
4708
|
+
provider = markProviderReady(initialized);
|
|
4685
4709
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4686
4710
|
return provider;
|
|
4687
4711
|
}
|
|
4688
4712
|
if (hasAPIEmbeddingConfig()) {
|
|
4689
4713
|
const initialized = await createAPIProvider(options);
|
|
4690
4714
|
if (initialized) {
|
|
4691
|
-
provider =
|
|
4715
|
+
provider = markProviderReady(initialized);
|
|
4692
4716
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4693
4717
|
return provider;
|
|
4694
4718
|
}
|
|
4695
4719
|
}
|
|
4696
4720
|
const localFallback = await createLocalFallbackProvider();
|
|
4697
4721
|
if (localFallback) {
|
|
4698
|
-
provider =
|
|
4722
|
+
provider = markProviderReady(localFallback);
|
|
4699
4723
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4700
4724
|
return provider;
|
|
4701
4725
|
}
|
|
@@ -4717,6 +4741,27 @@ async function isVectorSearchAvailable() {
|
|
|
4717
4741
|
const p = await getEmbeddingProvider();
|
|
4718
4742
|
return p !== null;
|
|
4719
4743
|
}
|
|
4744
|
+
function getEmbeddingRuntimeHealth() {
|
|
4745
|
+
const mode = getEmbeddingMode2();
|
|
4746
|
+
if (mode === "off") return { status: "disabled" };
|
|
4747
|
+
if (lastInitWasTemporaryFailure && lastEmbeddingFailure) {
|
|
4748
|
+
return {
|
|
4749
|
+
status: "degraded",
|
|
4750
|
+
failure: {
|
|
4751
|
+
kind: lastEmbeddingFailure.kind,
|
|
4752
|
+
occurredAt: new Date(lastEmbeddingFailure.occurredAt).toISOString(),
|
|
4753
|
+
retryAfterMs: Math.max(0, RETRY_COOLDOWN_MS - (Date.now() - lastEmbeddingFailure.occurredAt))
|
|
4754
|
+
}
|
|
4755
|
+
};
|
|
4756
|
+
}
|
|
4757
|
+
if (provider) {
|
|
4758
|
+
return {
|
|
4759
|
+
status: "ready",
|
|
4760
|
+
provider: { name: provider.name, dimensions: provider.dimensions }
|
|
4761
|
+
};
|
|
4762
|
+
}
|
|
4763
|
+
return { status: "uninitialized" };
|
|
4764
|
+
}
|
|
4720
4765
|
function isEmbeddingExplicitlyDisabled() {
|
|
4721
4766
|
return getEmbeddingMode2() === "off";
|
|
4722
4767
|
}
|
|
@@ -4725,10 +4770,11 @@ function resetProvider() {
|
|
|
4725
4770
|
initPromise = null;
|
|
4726
4771
|
lastInitWasTemporaryFailure = false;
|
|
4727
4772
|
lastFailureTimestamp = 0;
|
|
4773
|
+
lastEmbeddingFailure = null;
|
|
4728
4774
|
lastEmbeddingWarning = "";
|
|
4729
4775
|
lastEmbeddingWarningAt = 0;
|
|
4730
4776
|
}
|
|
4731
|
-
var EmbeddingInputError, UnsupportedEmbeddingModalityError, MAX_INLINE_EMBEDDING_BYTES, provider, initPromise, lastInitWasTemporaryFailure, lastEmbeddingWarning, lastEmbeddingWarningAt, WARNING_COOLDOWN_MS, RETRY_COOLDOWN_MS, lastFailureTimestamp;
|
|
4777
|
+
var EmbeddingInputError, UnsupportedEmbeddingModalityError, MAX_INLINE_EMBEDDING_BYTES, provider, initPromise, lastInitWasTemporaryFailure, lastEmbeddingFailure, lastEmbeddingWarning, lastEmbeddingWarningAt, WARNING_COOLDOWN_MS, RETRY_COOLDOWN_MS, lastFailureTimestamp;
|
|
4732
4778
|
var init_provider = __esm({
|
|
4733
4779
|
"src/embedding/provider.ts"() {
|
|
4734
4780
|
"use strict";
|
|
@@ -4753,6 +4799,7 @@ var init_provider = __esm({
|
|
|
4753
4799
|
provider = null;
|
|
4754
4800
|
initPromise = null;
|
|
4755
4801
|
lastInitWasTemporaryFailure = false;
|
|
4802
|
+
lastEmbeddingFailure = null;
|
|
4756
4803
|
lastEmbeddingWarning = "";
|
|
4757
4804
|
lastEmbeddingWarningAt = 0;
|
|
4758
4805
|
WARNING_COOLDOWN_MS = 3e4;
|
|
@@ -166096,7 +166143,7 @@ The path should point to a directory containing a .git folder.`
|
|
|
166096
166143
|
};
|
|
166097
166144
|
const server = existingServer ?? new McpServer({
|
|
166098
166145
|
name: "memorix",
|
|
166099
|
-
version: true ? "1.6.
|
|
166146
|
+
version: true ? "1.6.1" : "1.0.1"
|
|
166100
166147
|
});
|
|
166101
166148
|
const originalRegisterTool = server.registerTool.bind(server);
|
|
166102
166149
|
server.registerTool = ((name, ...args) => {
|
|
@@ -170502,7 +170549,7 @@ var init_serve_shared = __esm({
|
|
|
170502
170549
|
|
|
170503
170550
|
// src/cli/version.ts
|
|
170504
170551
|
function getCliVersion() {
|
|
170505
|
-
return true ? "1.6.
|
|
170552
|
+
return true ? "1.6.1" : pkg.version;
|
|
170506
170553
|
}
|
|
170507
170554
|
var init_version3 = __esm({
|
|
170508
170555
|
"src/cli/version.ts"() {
|
|
@@ -4308,6 +4308,7 @@ __export(provider_exports2, {
|
|
|
4308
4308
|
MAX_INLINE_EMBEDDING_BYTES: () => MAX_INLINE_EMBEDDING_BYTES,
|
|
4309
4309
|
UnsupportedEmbeddingModalityError: () => UnsupportedEmbeddingModalityError,
|
|
4310
4310
|
getEmbeddingProvider: () => getEmbeddingProvider,
|
|
4311
|
+
getEmbeddingRuntimeHealth: () => getEmbeddingRuntimeHealth,
|
|
4311
4312
|
isEmbeddingExplicitlyDisabled: () => isEmbeddingExplicitlyDisabled,
|
|
4312
4313
|
isVectorSearchAvailable: () => isVectorSearchAvailable,
|
|
4313
4314
|
resetProvider: () => resetProvider,
|
|
@@ -4415,13 +4416,36 @@ function isTemporaryEmbeddingFailure(error) {
|
|
|
4415
4416
|
if (!(error instanceof Error)) return false;
|
|
4416
4417
|
return /embedding api error \(401\)/i.test(error.message) || /invalid_api_key/i.test(error.message) || /incorrect api key/i.test(error.message) || /unauthorized/i.test(error.message) || /embedding api timeout/i.test(error.message) || /embedding api error \((402|429|5\d\d)\)/i.test(error.message) || /quota exceeded/i.test(error.message) || /account balance/i.test(error.message) || /fetch failed/i.test(error.message) || /econnreset/i.test(error.message) || /econnrefused/i.test(error.message) || /temporarily unavailable/i.test(error.message);
|
|
4417
4418
|
}
|
|
4419
|
+
function classifyEmbeddingFailure(error) {
|
|
4420
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4421
|
+
if (/embedding api error \(401\)|invalid_api_key|incorrect api key|unauthorized/i.test(message)) {
|
|
4422
|
+
return "authorization";
|
|
4423
|
+
}
|
|
4424
|
+
if (/embedding api error \(402\)|quota exceeded|account balance/i.test(message)) {
|
|
4425
|
+
return "billing";
|
|
4426
|
+
}
|
|
4427
|
+
if (/embedding api timeout|abort/i.test(message)) {
|
|
4428
|
+
return "timeout";
|
|
4429
|
+
}
|
|
4430
|
+
return "upstream";
|
|
4431
|
+
}
|
|
4418
4432
|
function markTemporaryFailure(reason) {
|
|
4419
4433
|
provider = null;
|
|
4420
4434
|
initPromise = null;
|
|
4421
4435
|
lastInitWasTemporaryFailure = true;
|
|
4422
4436
|
lastFailureTimestamp = Date.now();
|
|
4437
|
+
lastEmbeddingFailure = {
|
|
4438
|
+
kind: classifyEmbeddingFailure(reason),
|
|
4439
|
+
occurredAt: lastFailureTimestamp
|
|
4440
|
+
};
|
|
4423
4441
|
const message = reason instanceof Error ? reason.message : String(reason);
|
|
4424
|
-
warnOnce(`[memorix] Embedding provider
|
|
4442
|
+
warnOnce(`[memorix] Embedding provider unavailable at runtime: ${message}`);
|
|
4443
|
+
}
|
|
4444
|
+
function markProviderReady(candidate) {
|
|
4445
|
+
provider = wrapProvider(candidate);
|
|
4446
|
+
lastInitWasTemporaryFailure = false;
|
|
4447
|
+
lastEmbeddingFailure = null;
|
|
4448
|
+
return provider;
|
|
4425
4449
|
}
|
|
4426
4450
|
async function createFastEmbedProvider() {
|
|
4427
4451
|
try {
|
|
@@ -4537,35 +4561,35 @@ async function getEmbeddingProvider(options = {}) {
|
|
|
4537
4561
|
if (mode === "fastembed") {
|
|
4538
4562
|
const initialized = await createFastEmbedProvider();
|
|
4539
4563
|
if (!initialized) return null;
|
|
4540
|
-
provider =
|
|
4564
|
+
provider = markProviderReady(initialized);
|
|
4541
4565
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4542
4566
|
return provider;
|
|
4543
4567
|
}
|
|
4544
4568
|
if (mode === "transformers") {
|
|
4545
4569
|
const initialized = await createTransformersProvider();
|
|
4546
4570
|
if (!initialized) return null;
|
|
4547
|
-
provider =
|
|
4571
|
+
provider = markProviderReady(initialized);
|
|
4548
4572
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4549
4573
|
return provider;
|
|
4550
4574
|
}
|
|
4551
4575
|
if (mode === "api") {
|
|
4552
4576
|
const initialized = await createAPIProvider(options);
|
|
4553
4577
|
if (!initialized) return null;
|
|
4554
|
-
provider =
|
|
4578
|
+
provider = markProviderReady(initialized);
|
|
4555
4579
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4556
4580
|
return provider;
|
|
4557
4581
|
}
|
|
4558
4582
|
if (hasAPIEmbeddingConfig()) {
|
|
4559
4583
|
const initialized = await createAPIProvider(options);
|
|
4560
4584
|
if (initialized) {
|
|
4561
|
-
provider =
|
|
4585
|
+
provider = markProviderReady(initialized);
|
|
4562
4586
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4563
4587
|
return provider;
|
|
4564
4588
|
}
|
|
4565
4589
|
}
|
|
4566
4590
|
const localFallback = await createLocalFallbackProvider();
|
|
4567
4591
|
if (localFallback) {
|
|
4568
|
-
provider =
|
|
4592
|
+
provider = markProviderReady(localFallback);
|
|
4569
4593
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4570
4594
|
return provider;
|
|
4571
4595
|
}
|
|
@@ -4587,6 +4611,27 @@ async function isVectorSearchAvailable() {
|
|
|
4587
4611
|
const p = await getEmbeddingProvider();
|
|
4588
4612
|
return p !== null;
|
|
4589
4613
|
}
|
|
4614
|
+
function getEmbeddingRuntimeHealth() {
|
|
4615
|
+
const mode = getEmbeddingMode2();
|
|
4616
|
+
if (mode === "off") return { status: "disabled" };
|
|
4617
|
+
if (lastInitWasTemporaryFailure && lastEmbeddingFailure) {
|
|
4618
|
+
return {
|
|
4619
|
+
status: "degraded",
|
|
4620
|
+
failure: {
|
|
4621
|
+
kind: lastEmbeddingFailure.kind,
|
|
4622
|
+
occurredAt: new Date(lastEmbeddingFailure.occurredAt).toISOString(),
|
|
4623
|
+
retryAfterMs: Math.max(0, RETRY_COOLDOWN_MS - (Date.now() - lastEmbeddingFailure.occurredAt))
|
|
4624
|
+
}
|
|
4625
|
+
};
|
|
4626
|
+
}
|
|
4627
|
+
if (provider) {
|
|
4628
|
+
return {
|
|
4629
|
+
status: "ready",
|
|
4630
|
+
provider: { name: provider.name, dimensions: provider.dimensions }
|
|
4631
|
+
};
|
|
4632
|
+
}
|
|
4633
|
+
return { status: "uninitialized" };
|
|
4634
|
+
}
|
|
4590
4635
|
function isEmbeddingExplicitlyDisabled() {
|
|
4591
4636
|
return getEmbeddingMode2() === "off";
|
|
4592
4637
|
}
|
|
@@ -4595,10 +4640,11 @@ function resetProvider() {
|
|
|
4595
4640
|
initPromise = null;
|
|
4596
4641
|
lastInitWasTemporaryFailure = false;
|
|
4597
4642
|
lastFailureTimestamp = 0;
|
|
4643
|
+
lastEmbeddingFailure = null;
|
|
4598
4644
|
lastEmbeddingWarning = "";
|
|
4599
4645
|
lastEmbeddingWarningAt = 0;
|
|
4600
4646
|
}
|
|
4601
|
-
var EmbeddingInputError, UnsupportedEmbeddingModalityError, MAX_INLINE_EMBEDDING_BYTES, provider, initPromise, lastInitWasTemporaryFailure, lastEmbeddingWarning, lastEmbeddingWarningAt, WARNING_COOLDOWN_MS, RETRY_COOLDOWN_MS, lastFailureTimestamp;
|
|
4647
|
+
var EmbeddingInputError, UnsupportedEmbeddingModalityError, MAX_INLINE_EMBEDDING_BYTES, provider, initPromise, lastInitWasTemporaryFailure, lastEmbeddingFailure, lastEmbeddingWarning, lastEmbeddingWarningAt, WARNING_COOLDOWN_MS, RETRY_COOLDOWN_MS, lastFailureTimestamp;
|
|
4602
4648
|
var init_provider2 = __esm({
|
|
4603
4649
|
"src/embedding/provider.ts"() {
|
|
4604
4650
|
"use strict";
|
|
@@ -4623,6 +4669,7 @@ var init_provider2 = __esm({
|
|
|
4623
4669
|
provider = null;
|
|
4624
4670
|
initPromise = null;
|
|
4625
4671
|
lastInitWasTemporaryFailure = false;
|
|
4672
|
+
lastEmbeddingFailure = null;
|
|
4626
4673
|
lastEmbeddingWarning = "";
|
|
4627
4674
|
lastEmbeddingWarningAt = 0;
|
|
4628
4675
|
WARNING_COOLDOWN_MS = 3e4;
|
|
@@ -4189,6 +4189,7 @@ __export(provider_exports, {
|
|
|
4189
4189
|
MAX_INLINE_EMBEDDING_BYTES: () => MAX_INLINE_EMBEDDING_BYTES,
|
|
4190
4190
|
UnsupportedEmbeddingModalityError: () => UnsupportedEmbeddingModalityError,
|
|
4191
4191
|
getEmbeddingProvider: () => getEmbeddingProvider,
|
|
4192
|
+
getEmbeddingRuntimeHealth: () => getEmbeddingRuntimeHealth,
|
|
4192
4193
|
isEmbeddingExplicitlyDisabled: () => isEmbeddingExplicitlyDisabled,
|
|
4193
4194
|
isVectorSearchAvailable: () => isVectorSearchAvailable,
|
|
4194
4195
|
resetProvider: () => resetProvider,
|
|
@@ -4296,13 +4297,36 @@ function isTemporaryEmbeddingFailure(error) {
|
|
|
4296
4297
|
if (!(error instanceof Error)) return false;
|
|
4297
4298
|
return /embedding api error \(401\)/i.test(error.message) || /invalid_api_key/i.test(error.message) || /incorrect api key/i.test(error.message) || /unauthorized/i.test(error.message) || /embedding api timeout/i.test(error.message) || /embedding api error \((402|429|5\d\d)\)/i.test(error.message) || /quota exceeded/i.test(error.message) || /account balance/i.test(error.message) || /fetch failed/i.test(error.message) || /econnreset/i.test(error.message) || /econnrefused/i.test(error.message) || /temporarily unavailable/i.test(error.message);
|
|
4298
4299
|
}
|
|
4300
|
+
function classifyEmbeddingFailure(error) {
|
|
4301
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4302
|
+
if (/embedding api error \(401\)|invalid_api_key|incorrect api key|unauthorized/i.test(message)) {
|
|
4303
|
+
return "authorization";
|
|
4304
|
+
}
|
|
4305
|
+
if (/embedding api error \(402\)|quota exceeded|account balance/i.test(message)) {
|
|
4306
|
+
return "billing";
|
|
4307
|
+
}
|
|
4308
|
+
if (/embedding api timeout|abort/i.test(message)) {
|
|
4309
|
+
return "timeout";
|
|
4310
|
+
}
|
|
4311
|
+
return "upstream";
|
|
4312
|
+
}
|
|
4299
4313
|
function markTemporaryFailure(reason) {
|
|
4300
4314
|
provider = null;
|
|
4301
4315
|
initPromise = null;
|
|
4302
4316
|
lastInitWasTemporaryFailure = true;
|
|
4303
4317
|
lastFailureTimestamp = Date.now();
|
|
4318
|
+
lastEmbeddingFailure = {
|
|
4319
|
+
kind: classifyEmbeddingFailure(reason),
|
|
4320
|
+
occurredAt: lastFailureTimestamp
|
|
4321
|
+
};
|
|
4304
4322
|
const message = reason instanceof Error ? reason.message : String(reason);
|
|
4305
|
-
warnOnce(`[memorix] Embedding provider
|
|
4323
|
+
warnOnce(`[memorix] Embedding provider unavailable at runtime: ${message}`);
|
|
4324
|
+
}
|
|
4325
|
+
function markProviderReady(candidate) {
|
|
4326
|
+
provider = wrapProvider(candidate);
|
|
4327
|
+
lastInitWasTemporaryFailure = false;
|
|
4328
|
+
lastEmbeddingFailure = null;
|
|
4329
|
+
return provider;
|
|
4306
4330
|
}
|
|
4307
4331
|
async function createFastEmbedProvider() {
|
|
4308
4332
|
try {
|
|
@@ -4418,35 +4442,35 @@ async function getEmbeddingProvider(options = {}) {
|
|
|
4418
4442
|
if (mode === "fastembed") {
|
|
4419
4443
|
const initialized = await createFastEmbedProvider();
|
|
4420
4444
|
if (!initialized) return null;
|
|
4421
|
-
provider =
|
|
4445
|
+
provider = markProviderReady(initialized);
|
|
4422
4446
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4423
4447
|
return provider;
|
|
4424
4448
|
}
|
|
4425
4449
|
if (mode === "transformers") {
|
|
4426
4450
|
const initialized = await createTransformersProvider();
|
|
4427
4451
|
if (!initialized) return null;
|
|
4428
|
-
provider =
|
|
4452
|
+
provider = markProviderReady(initialized);
|
|
4429
4453
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4430
4454
|
return provider;
|
|
4431
4455
|
}
|
|
4432
4456
|
if (mode === "api") {
|
|
4433
4457
|
const initialized = await createAPIProvider(options);
|
|
4434
4458
|
if (!initialized) return null;
|
|
4435
|
-
provider =
|
|
4459
|
+
provider = markProviderReady(initialized);
|
|
4436
4460
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4437
4461
|
return provider;
|
|
4438
4462
|
}
|
|
4439
4463
|
if (hasAPIEmbeddingConfig()) {
|
|
4440
4464
|
const initialized = await createAPIProvider(options);
|
|
4441
4465
|
if (initialized) {
|
|
4442
|
-
provider =
|
|
4466
|
+
provider = markProviderReady(initialized);
|
|
4443
4467
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4444
4468
|
return provider;
|
|
4445
4469
|
}
|
|
4446
4470
|
}
|
|
4447
4471
|
const localFallback = await createLocalFallbackProvider();
|
|
4448
4472
|
if (localFallback) {
|
|
4449
|
-
provider =
|
|
4473
|
+
provider = markProviderReady(localFallback);
|
|
4450
4474
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
4451
4475
|
return provider;
|
|
4452
4476
|
}
|
|
@@ -4468,6 +4492,27 @@ async function isVectorSearchAvailable() {
|
|
|
4468
4492
|
const p = await getEmbeddingProvider();
|
|
4469
4493
|
return p !== null;
|
|
4470
4494
|
}
|
|
4495
|
+
function getEmbeddingRuntimeHealth() {
|
|
4496
|
+
const mode = getEmbeddingMode2();
|
|
4497
|
+
if (mode === "off") return { status: "disabled" };
|
|
4498
|
+
if (lastInitWasTemporaryFailure && lastEmbeddingFailure) {
|
|
4499
|
+
return {
|
|
4500
|
+
status: "degraded",
|
|
4501
|
+
failure: {
|
|
4502
|
+
kind: lastEmbeddingFailure.kind,
|
|
4503
|
+
occurredAt: new Date(lastEmbeddingFailure.occurredAt).toISOString(),
|
|
4504
|
+
retryAfterMs: Math.max(0, RETRY_COOLDOWN_MS - (Date.now() - lastEmbeddingFailure.occurredAt))
|
|
4505
|
+
}
|
|
4506
|
+
};
|
|
4507
|
+
}
|
|
4508
|
+
if (provider) {
|
|
4509
|
+
return {
|
|
4510
|
+
status: "ready",
|
|
4511
|
+
provider: { name: provider.name, dimensions: provider.dimensions }
|
|
4512
|
+
};
|
|
4513
|
+
}
|
|
4514
|
+
return { status: "uninitialized" };
|
|
4515
|
+
}
|
|
4471
4516
|
function isEmbeddingExplicitlyDisabled() {
|
|
4472
4517
|
return getEmbeddingMode2() === "off";
|
|
4473
4518
|
}
|
|
@@ -4476,10 +4521,11 @@ function resetProvider() {
|
|
|
4476
4521
|
initPromise = null;
|
|
4477
4522
|
lastInitWasTemporaryFailure = false;
|
|
4478
4523
|
lastFailureTimestamp = 0;
|
|
4524
|
+
lastEmbeddingFailure = null;
|
|
4479
4525
|
lastEmbeddingWarning = "";
|
|
4480
4526
|
lastEmbeddingWarningAt = 0;
|
|
4481
4527
|
}
|
|
4482
|
-
var EmbeddingInputError, UnsupportedEmbeddingModalityError, MAX_INLINE_EMBEDDING_BYTES, provider, initPromise, lastInitWasTemporaryFailure, lastEmbeddingWarning, lastEmbeddingWarningAt, WARNING_COOLDOWN_MS, RETRY_COOLDOWN_MS, lastFailureTimestamp;
|
|
4528
|
+
var EmbeddingInputError, UnsupportedEmbeddingModalityError, MAX_INLINE_EMBEDDING_BYTES, provider, initPromise, lastInitWasTemporaryFailure, lastEmbeddingFailure, lastEmbeddingWarning, lastEmbeddingWarningAt, WARNING_COOLDOWN_MS, RETRY_COOLDOWN_MS, lastFailureTimestamp;
|
|
4483
4529
|
var init_provider = __esm({
|
|
4484
4530
|
"src/embedding/provider.ts"() {
|
|
4485
4531
|
"use strict";
|
|
@@ -4504,6 +4550,7 @@ var init_provider = __esm({
|
|
|
4504
4550
|
provider = null;
|
|
4505
4551
|
initPromise = null;
|
|
4506
4552
|
lastInitWasTemporaryFailure = false;
|
|
4553
|
+
lastEmbeddingFailure = null;
|
|
4507
4554
|
lastEmbeddingWarning = "";
|
|
4508
4555
|
lastEmbeddingWarningAt = 0;
|
|
4509
4556
|
WARNING_COOLDOWN_MS = 3e4;
|
|
@@ -3206,6 +3206,7 @@ __export(provider_exports, {
|
|
|
3206
3206
|
MAX_INLINE_EMBEDDING_BYTES: () => MAX_INLINE_EMBEDDING_BYTES,
|
|
3207
3207
|
UnsupportedEmbeddingModalityError: () => UnsupportedEmbeddingModalityError,
|
|
3208
3208
|
getEmbeddingProvider: () => getEmbeddingProvider,
|
|
3209
|
+
getEmbeddingRuntimeHealth: () => getEmbeddingRuntimeHealth,
|
|
3209
3210
|
isEmbeddingExplicitlyDisabled: () => isEmbeddingExplicitlyDisabled,
|
|
3210
3211
|
isVectorSearchAvailable: () => isVectorSearchAvailable,
|
|
3211
3212
|
resetProvider: () => resetProvider,
|
|
@@ -3313,13 +3314,36 @@ function isTemporaryEmbeddingFailure(error) {
|
|
|
3313
3314
|
if (!(error instanceof Error)) return false;
|
|
3314
3315
|
return /embedding api error \(401\)/i.test(error.message) || /invalid_api_key/i.test(error.message) || /incorrect api key/i.test(error.message) || /unauthorized/i.test(error.message) || /embedding api timeout/i.test(error.message) || /embedding api error \((402|429|5\d\d)\)/i.test(error.message) || /quota exceeded/i.test(error.message) || /account balance/i.test(error.message) || /fetch failed/i.test(error.message) || /econnreset/i.test(error.message) || /econnrefused/i.test(error.message) || /temporarily unavailable/i.test(error.message);
|
|
3315
3316
|
}
|
|
3317
|
+
function classifyEmbeddingFailure(error) {
|
|
3318
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3319
|
+
if (/embedding api error \(401\)|invalid_api_key|incorrect api key|unauthorized/i.test(message)) {
|
|
3320
|
+
return "authorization";
|
|
3321
|
+
}
|
|
3322
|
+
if (/embedding api error \(402\)|quota exceeded|account balance/i.test(message)) {
|
|
3323
|
+
return "billing";
|
|
3324
|
+
}
|
|
3325
|
+
if (/embedding api timeout|abort/i.test(message)) {
|
|
3326
|
+
return "timeout";
|
|
3327
|
+
}
|
|
3328
|
+
return "upstream";
|
|
3329
|
+
}
|
|
3316
3330
|
function markTemporaryFailure(reason) {
|
|
3317
3331
|
provider = null;
|
|
3318
3332
|
initPromise = null;
|
|
3319
3333
|
lastInitWasTemporaryFailure = true;
|
|
3320
3334
|
lastFailureTimestamp = Date.now();
|
|
3335
|
+
lastEmbeddingFailure = {
|
|
3336
|
+
kind: classifyEmbeddingFailure(reason),
|
|
3337
|
+
occurredAt: lastFailureTimestamp
|
|
3338
|
+
};
|
|
3321
3339
|
const message = reason instanceof Error ? reason.message : String(reason);
|
|
3322
|
-
warnOnce(`[memorix] Embedding provider
|
|
3340
|
+
warnOnce(`[memorix] Embedding provider unavailable at runtime: ${message}`);
|
|
3341
|
+
}
|
|
3342
|
+
function markProviderReady(candidate) {
|
|
3343
|
+
provider = wrapProvider(candidate);
|
|
3344
|
+
lastInitWasTemporaryFailure = false;
|
|
3345
|
+
lastEmbeddingFailure = null;
|
|
3346
|
+
return provider;
|
|
3323
3347
|
}
|
|
3324
3348
|
async function createFastEmbedProvider() {
|
|
3325
3349
|
try {
|
|
@@ -3435,35 +3459,35 @@ async function getEmbeddingProvider(options = {}) {
|
|
|
3435
3459
|
if (mode === "fastembed") {
|
|
3436
3460
|
const initialized = await createFastEmbedProvider();
|
|
3437
3461
|
if (!initialized) return null;
|
|
3438
|
-
provider =
|
|
3462
|
+
provider = markProviderReady(initialized);
|
|
3439
3463
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
3440
3464
|
return provider;
|
|
3441
3465
|
}
|
|
3442
3466
|
if (mode === "transformers") {
|
|
3443
3467
|
const initialized = await createTransformersProvider();
|
|
3444
3468
|
if (!initialized) return null;
|
|
3445
|
-
provider =
|
|
3469
|
+
provider = markProviderReady(initialized);
|
|
3446
3470
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
3447
3471
|
return provider;
|
|
3448
3472
|
}
|
|
3449
3473
|
if (mode === "api") {
|
|
3450
3474
|
const initialized = await createAPIProvider(options);
|
|
3451
3475
|
if (!initialized) return null;
|
|
3452
|
-
provider =
|
|
3476
|
+
provider = markProviderReady(initialized);
|
|
3453
3477
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
3454
3478
|
return provider;
|
|
3455
3479
|
}
|
|
3456
3480
|
if (hasAPIEmbeddingConfig()) {
|
|
3457
3481
|
const initialized = await createAPIProvider(options);
|
|
3458
3482
|
if (initialized) {
|
|
3459
|
-
provider =
|
|
3483
|
+
provider = markProviderReady(initialized);
|
|
3460
3484
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
3461
3485
|
return provider;
|
|
3462
3486
|
}
|
|
3463
3487
|
}
|
|
3464
3488
|
const localFallback = await createLocalFallbackProvider();
|
|
3465
3489
|
if (localFallback) {
|
|
3466
|
-
provider =
|
|
3490
|
+
provider = markProviderReady(localFallback);
|
|
3467
3491
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
3468
3492
|
return provider;
|
|
3469
3493
|
}
|
|
@@ -3485,6 +3509,27 @@ async function isVectorSearchAvailable() {
|
|
|
3485
3509
|
const p = await getEmbeddingProvider();
|
|
3486
3510
|
return p !== null;
|
|
3487
3511
|
}
|
|
3512
|
+
function getEmbeddingRuntimeHealth() {
|
|
3513
|
+
const mode = getEmbeddingMode2();
|
|
3514
|
+
if (mode === "off") return { status: "disabled" };
|
|
3515
|
+
if (lastInitWasTemporaryFailure && lastEmbeddingFailure) {
|
|
3516
|
+
return {
|
|
3517
|
+
status: "degraded",
|
|
3518
|
+
failure: {
|
|
3519
|
+
kind: lastEmbeddingFailure.kind,
|
|
3520
|
+
occurredAt: new Date(lastEmbeddingFailure.occurredAt).toISOString(),
|
|
3521
|
+
retryAfterMs: Math.max(0, RETRY_COOLDOWN_MS - (Date.now() - lastEmbeddingFailure.occurredAt))
|
|
3522
|
+
}
|
|
3523
|
+
};
|
|
3524
|
+
}
|
|
3525
|
+
if (provider) {
|
|
3526
|
+
return {
|
|
3527
|
+
status: "ready",
|
|
3528
|
+
provider: { name: provider.name, dimensions: provider.dimensions }
|
|
3529
|
+
};
|
|
3530
|
+
}
|
|
3531
|
+
return { status: "uninitialized" };
|
|
3532
|
+
}
|
|
3488
3533
|
function isEmbeddingExplicitlyDisabled() {
|
|
3489
3534
|
return getEmbeddingMode2() === "off";
|
|
3490
3535
|
}
|
|
@@ -3493,10 +3538,11 @@ function resetProvider() {
|
|
|
3493
3538
|
initPromise = null;
|
|
3494
3539
|
lastInitWasTemporaryFailure = false;
|
|
3495
3540
|
lastFailureTimestamp = 0;
|
|
3541
|
+
lastEmbeddingFailure = null;
|
|
3496
3542
|
lastEmbeddingWarning = "";
|
|
3497
3543
|
lastEmbeddingWarningAt = 0;
|
|
3498
3544
|
}
|
|
3499
|
-
var EmbeddingInputError, UnsupportedEmbeddingModalityError, MAX_INLINE_EMBEDDING_BYTES, provider, initPromise, lastInitWasTemporaryFailure, lastEmbeddingWarning, lastEmbeddingWarningAt, WARNING_COOLDOWN_MS, RETRY_COOLDOWN_MS, lastFailureTimestamp;
|
|
3545
|
+
var EmbeddingInputError, UnsupportedEmbeddingModalityError, MAX_INLINE_EMBEDDING_BYTES, provider, initPromise, lastInitWasTemporaryFailure, lastEmbeddingFailure, lastEmbeddingWarning, lastEmbeddingWarningAt, WARNING_COOLDOWN_MS, RETRY_COOLDOWN_MS, lastFailureTimestamp;
|
|
3500
3546
|
var init_provider = __esm({
|
|
3501
3547
|
"src/embedding/provider.ts"() {
|
|
3502
3548
|
"use strict";
|
|
@@ -3521,6 +3567,7 @@ var init_provider = __esm({
|
|
|
3521
3567
|
provider = null;
|
|
3522
3568
|
initPromise = null;
|
|
3523
3569
|
lastInitWasTemporaryFailure = false;
|
|
3570
|
+
lastEmbeddingFailure = null;
|
|
3524
3571
|
lastEmbeddingWarning = "";
|
|
3525
3572
|
lastEmbeddingWarningAt = 0;
|
|
3526
3573
|
WARNING_COOLDOWN_MS = 3e4;
|
|
@@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [1.6.1] - 2026-08-17
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- **Bounded hook lifecycle on every desktop platform** -- `memorix hook` now
|
|
11
|
+
reads stdin with an idle bound, performs embedding writes in the deferred
|
|
12
|
+
lane, and has a hard process deadline. The hook-specific V8 heap is 512 MiB
|
|
13
|
+
instead of the control plane's 4 GiB. This prevents hung hook processes and
|
|
14
|
+
associated CPU or memory pressure on macOS, Windows, and Linux. The Windows
|
|
15
|
+
CLI heap restart also hides its child console window.
|
|
16
|
+
- **Recoverable HTTP MCP sessions** -- HTTP MCP sessions now default to a
|
|
17
|
+
12-hour idle window. An expired or unknown session receives a fast `404`
|
|
18
|
+
with a reinitialize hint instead of looking like a silent client hang. Set
|
|
19
|
+
`MEMORIX_SESSION_TIMEOUT_MS=0` only when the host owns lifecycle cleanup.
|
|
20
|
+
- **Truthful embedding diagnostics** -- the HTTP control plane exposes its
|
|
21
|
+
real runtime embedding state. `memorix doctor` reads that state instead of
|
|
22
|
+
reporting a fresh local probe as ready while the running service is degraded
|
|
23
|
+
by authorization, billing, timeout, or upstream failure.
|
|
24
|
+
- **Accurate doctor JSON health** -- a live PID with an unreachable HTTP
|
|
25
|
+
control plane now reports `healthy: false` rather than a false positive.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- **macOS release coverage** -- normal CI now runs the full build and test
|
|
29
|
+
suite on `macos-latest` in addition to Ubuntu and Windows.
|
|
30
|
+
|
|
7
31
|
## [1.6.0] - 2026-08-17
|
|
8
32
|
|
|
9
33
|
### Added
|