Skip to content

fix(embeddings): persist model cache outside node_modules - #179

Open
HengYangDS wants to merge 4 commits into
obra:mainfrom
HengYangDS:fix/persistent-model-cache
Open

HengYangDS wants to merge 4 commits into
obra:mainfrom
HengYangDS:fix/persistent-model-cache

Conversation

@HengYangDS

@HengYangDS HengYangDS commented Sep 26, 2026 •

Copy link
Copy Markdown

Summary

Clean Node 22 / Node 26 qualification at e5a4672

This repository intentionally ignores package-lock.json and CI uses npm install. An isolated resolver comparison showed that ^4.2.0 selects Transformers.js 4.3.0, onnxruntime-node 1.30.0, and onnxruntime-web 1.31.0-dev; the one-line exact 4.2.0 constraint selects onnxruntime-node 1.24.3 and onnxruntime-web 1.26.0-dev. No lockfile, host path, or runtime fallback was added.

Two independent git archive snapshots from this PR HEAD started without node_modules or a lockfile. On macOS arm64, Node 22.23.3 (ABI 127) and Node 26.10.0 (ABI 147) each completed one standard npm install --no-audit --no-fund --foreground-scripts in about 12 seconds using a warmed package cache. In each tree, better-sqlite3 and sqlite-vec instantiated successfully, the hash-verified pre-seeded embedding model loaded with remote loading disabled, npm run build and bundle syntax passed, and the full suite passed 359/359 tests. The checked-in MCP bundle also completed isolated search and read calls against a synthetic fixture with those clean dependencies. Node 22 reported an optional fsevents build warning; the install exited zero and all validators passed. These runs do not prove an empty-cache network install or Ubuntu CI.

Node 24 qualification: not green

At the previous PR head 21988fa, an earlier Node 24.21.0 (ABI 137) run passed native loading, build, bundle syntax, and the four Codex manifest tests, but the full suite stopped after 313/359 tests when six workers aborted in better-sqlite3 cleanup. Its cloned dependency tree contained Vitest 5.0.0 even though this branch declares ^3.2.4, so that run is not a valid clean-install qualification. That earlier Node 22 run is superseded by the current-head clean qualification above. Earlier clean Node 22/24 runs on the parent commit used Vitest 3.2.7, but do not establish a current-head Node 24 full-suite pass.

One bounded, empty-node_modules install from the previous HEAD 21988fa was attempted on Node 24.21.0. It did not complete within 600 seconds while resolving/fetching onnxruntime-node@1.30.0 after @huggingface/transformers resolved to 4.3.0. No second unchanged cold-install attempt was made, and a clean full-suite pass is not claimed. The partial resolver tree did contain the manifest-compatible Vitest 3.2.7 and better-sqlite3 12.11.1; the latter was built from source against the installed Node 24.21.0 headers and instantiated successfully with sqlite-vec.

The native abort is independently reproducible without Episodic Memory, Transformers.js, Vitest, or sqlite-vec. With better-sqlite3@12.11.1 compiled against Node 24.21.0 headers, the following standalone script aborts in node::RemoveEnvironmentCleanupHook from Database::~Database() (ABI 137). The identical script passes on Node 26.10.0 after rebuilding the same addon version against ABI 147:

import assert from 'node:assert/strict';
import Database from 'better-sqlite3';

for (let iteration = 0; iteration < 500; iteration++) {
  const db = new Database(':memory:');
  for (let value = 0; value < 10; value++) {
    assert.deepEqual(db.prepare('SELECT ? AS value').get(value), { value });
  }
  db.close();
}

Node's built-in test runner and Vitest 3.2.7 also reproduce the same assertion. This matches nodejs/node#65446 and WiseLibs/better-sqlite3#1515: a Node 24 node::ObjectWrap cleanup-hook regression. The proposed 24.x backport is closed without merge as of 2026-09-27. A Node 24 release containing the upstream fix is the external prerequisite for a green Node 24 qualification; until then, Node 22 or 26 can be qualified separately. We will not hide this with a host-specific path or header workaround in the plugin.

Other limits

  • Upstream workflow checks have not run for this fork PR; no CI pass or merge-readiness claim is made.
  • A one-shot empty-cache model download and Ubuntu runtime qualification remain unverified. Explicit offline mode with an empty model cache fails promptly with a clear diagnostic.
  • The large dist/mcp-server.js diff is generated bundle churn from the unpinned transitive dependency graph. Source changes are confined to cache policy, Codex environment forwarding, dependency policy, sync status, tests, and docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant