From af3cd7f07fe4a9fda6aa9693dfc820ce1f52ff8d Mon Sep 17 00:00:00 2001 From: chopratejas Date: Sun, 12 Apr 2026 09:17:15 -0700 Subject: [PATCH] =?UTF-8?q?Fix=20#149:=20memory=20crash=20in=20Docker=20?= =?UTF-8?q?=E2=80=94=20missing=20vector=20index=20+=20pthread=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three fixes for Docker-native install with --memory: 1. Add sqlite-vec to proxy extras — memory's vector index now installs with pip install headroom-ai[proxy]. No separate pip install needed. 2. Fix AUTO vector backend fallback — was: SQLITE_VEC → HNSW → crash. Now: SQLITE_VEC → HNSW → clear error message listing install options. 3. Fix ONNX pthread_setaffinity_np error in Docker containers — set intra/inter thread count to 1 in SessionOptions. Prevents the "Invalid argument" error on containers with limited CPU affinity. --- headroom/memory/adapters/embedders.py | 8 +++++++- headroom/memory/factory.py | 13 ++++++++++--- pyproject.toml | 1 + 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/headroom/memory/adapters/embedders.py b/headroom/memory/adapters/embedders.py index 547b54da3..d04534e64 100644 --- a/headroom/memory/adapters/embedders.py +++ b/headroom/memory/adapters/embedders.py @@ -311,7 +311,13 @@ class OnnxLocalEmbedder: model_path = hf_hub_download(self.ONNX_REPO, "model.onnx") tok_path = hf_hub_download(self.ONNX_REPO, "tokenizer.json") - self._session = ort.InferenceSession(model_path, providers=["CPUExecutionProvider"]) + # Set thread count to avoid pthread_setaffinity_np errors in Docker containers + sess_options = ort.SessionOptions() + sess_options.intra_op_num_threads = 1 + sess_options.inter_op_num_threads = 1 + self._session = ort.InferenceSession( + model_path, sess_options, providers=["CPUExecutionProvider"] + ) self._tokenizer = Tokenizer.from_file(tok_path) self._tokenizer.enable_truncation(max_length=self._max_length) self._tokenizer.enable_padding(length=self._max_length) diff --git a/headroom/memory/factory.py b/headroom/memory/factory.py index c90b27411..bbecd971a 100644 --- a/headroom/memory/factory.py +++ b/headroom/memory/factory.py @@ -148,14 +148,21 @@ def _create_vector_index(config: MemoryConfig) -> VectorIndex: """ backend = config.vector_backend - # AUTO: prefer SQLITE_VEC if available, else HNSW + # AUTO: prefer SQLITE_VEC → HNSW → fail with helpful message if backend == VectorBackend.AUTO: - from headroom.memory.adapters import SQLITE_VEC_AVAILABLE + from headroom.memory.adapters import HNSW_AVAILABLE, SQLITE_VEC_AVAILABLE if SQLITE_VEC_AVAILABLE: backend = VectorBackend.SQLITE_VEC - else: + elif HNSW_AVAILABLE: backend = VectorBackend.HNSW + else: + raise ValueError( + "No vector index backend available for memory. Install one:\n" + " pip install sqlite-vec (recommended, lightweight)\n" + " pip install hnswlib (alternative)\n" + "Or install the full proxy bundle: pip install headroom-ai[proxy]" + ) if backend == VectorBackend.SQLITE_VEC: from headroom.memory.adapters import SQLITE_VEC_AVAILABLE diff --git a/pyproject.toml b/pyproject.toml index 55b4c427f..e569d96fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,6 +67,7 @@ proxy = [ "onnxruntime>=1.16.0", # Kompress ONNX INT8 text compression (no torch needed) "transformers>=4.30.0", # Tokenizer only (for Kompress) "watchdog>=4.0.0", # File watcher for live code graph reindexing (--code-graph) + "sqlite-vec>=0.1.6", # Vector index for memory (--memory). Lightweight, no torch. ] # AST-based code compression (tree-sitter) code = [