Skip to content

fix(router): lazy-load onnxruntime-node to stop crashing Windows imports - #230

Merged
ruvnet merged 1 commit into
mainfrom
fix/onnx-local-lazy-load-windows
Sep 16, 2026
Merged

ruvnet merged 1 commit into
mainfrom
fix/onnx-local-lazy-load-windows

Conversation

@ruvnet

@ruvnet ruvnet commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Summary

Rebases the core fix from #155 onto current main. `onnx-local.ts` and `onnx-local-optimized.ts` both did a top-level `await import('onnxruntime-node')` at module load time, firing the native-binding load as a side effect of merely importing the module — even for consumers that never touch the ONNX router (e.g. `reasoningbank`, via `core/distill -> router/router`). On Windows environments where the NAPI binary can't load, this crashes the whole import chain.

#155 couldn't be merged as-is: it was based on a pre-#154/#228 snapshot, and its `@xenova/transformers` hunks no longer apply now that main has fully migrated to `@huggingface/transformers`. This PR cherry-picks just the lazy-load refactor, preserving the `PHI4_MODEL_PATH`/`MODEL_ROOT` centralization #228 already landed.

Changes

  • `onnx-local.ts`: moves the `onnxruntime-node` import into a `loadOrt()` helper, called from `initializeSession()` instead of at module scope.
  • `onnx-local-optimized.ts`: drops its own top-level eager import entirely — it never referenced the resulting binding at all; the base class it extends is the only thing that needs it.

Verification

Reasoned proof isn't enough for an import-time side effect, so this was verified empirically: stubbed `onnxruntime-node` with a load-marker side effect and confirmed:

  • Pre-fix: the marker fires on unconditional `import()` of the module (bug reproduced).
  • Post-fix: the marker does not fire on import, but does fire once `chat()` actually invokes `initializeSession()` — confirming this is a genuine lazy-load, not "never loads."

`npx tsc -p config/tsconfig.json --skipLibCheck` — clean, no new errors.

Closes #155.

🤖 Generated with RuFlo

https://claude.ai/code/session_01SjxUvZnyBdwtx4Y1jKAqt6

onnx-local.ts and onnx-local-optimized.ts both did a top-level
`await import('onnxruntime-node')` at module load time, which fires the
native-binding load (onnxruntime_binding.node) as a side effect of merely
importing the module — even for consumers that never touch the ONNX
router at all (e.g. reasoningbank, via core/distill -> router/router).
On Windows environments where the NAPI binary can't load, this crashes
the whole import chain.

Moves the load into a `loadOrt()` helper invoked lazily from
initializeSession() (onnx-local.ts), and drops the eager load entirely
from onnx-local-optimized.ts, which never referenced the resulting `ort`
binding at all — the base class it extends is the only thing that needs it.

Rebased from PR #155 (thanks to the original author) — cherry-picked just
this lazy-load refactor onto current main, since #155 was based on a
pre-#154/#228 snapshot and its @xenova/transformers hunks no longer apply
(main has since migrated fully to @huggingface/transformers).

Verified empirically (not just by reasoning about it): stubbed
onnxruntime-node with a load-marker side effect, confirmed the marker
fires on unconditional `import()` of the pre-fix module (bug reproduced)
and does not fire post-fix — while still firing once `chat()` actually
invokes initializeSession() (confirming lazy-load isn't just "never loads").

Closes #155.

Co-Authored-By: RuFlo <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01SjxUvZnyBdwtx4Y1jKAqt6
@ruvnet
ruvnet merged commit 68296cb into main Sep 16, 2026
3 checks passed
@ruvnet
ruvnet deleted the fix/onnx-local-lazy-load-windows branch September 16, 2026 03:53
ruvnet added a commit that referenced this pull request Sep 16, 2026
Patch release consolidating this cycle's PR triage (see ADR-078):
- Windows fix: onnxruntime-node is now lazy-loaded instead of loaded at
  module-import time, which crashed environments where the native binding
  can't load (#230, rebased from #155).
- ESM __dirname polyfill for agentdb-cli.ts (#78).
- agentic-jujutsu: jj bookmark migration for jj >=0.21 (#174), darwin-arm64
  optional dependency (#160).
- Fully-local (no API key) path fixes: PROXY_PORT threading, --provider
  ollama exclusion, ONNX model path centralization (#228).
- SECURITY.md stub (#166), 32 new example applications (#62).

No breaking changes, no public API changes.


Claude-Session: https://claude.ai/code/session_01SjxUvZnyBdwtx4Y1jKAqt6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant