Fix base CI issues and the defaults in .env.example (#24)

* Add the LLM_PROVIDER in example

* fix the assert in testing recall

* trial to fix failing client tests

NotImplementedError: Cannot copy out of meta tensor; no data! Please use torch.nn.Module.to_empty() instead of torch.nn.Module.to() when moving module from meta to a different device.

* lock the sentence transformer packages to align with the breaking changes around lazy tensor loading

* Add the LLM_PROVIDER in example

* fix the assert in testing recall

* trial to fix failing client tests

* pre-cache the model so CI doesn't need workarounds

* remove assert that is a race condition

The test was checking that the bank count increased, but with parallel tests (-n 8), other tests can delete their banks while this test is running, causing a race condition. The important assertion is assert test_bank_id in final_banks - which verifies the bank was actually created.

* add debug to figure out why docker build fails sometimes

* use the CPU only version of pytorch to avoid pulling cuda libraries

* add best match strategy to uv

* change the example openai model
This commit is contained in:
Derek Bouius 2025-12-11 16:48:12 -05:00 committed by GitHub
parent 158a6aac9a
commit d6b7b9b398
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 52 additions and 19 deletions

View file

@ -2,8 +2,9 @@
# Copy this file to .env and fill in your values # Copy this file to .env and fill in your values
# LLM Configuration (Required) # LLM Configuration (Required)
HINDSIGHT_API_LLM_PROVIDER=openai
HINDSIGHT_API_LLM_API_KEY=your-api-key-here HINDSIGHT_API_LLM_API_KEY=your-api-key-here
HINDSIGHT_API_LLM_MODEL=gpt-4o-mini HINDSIGHT_API_LLM_MODEL=o3-mini
HINDSIGHT_API_LLM_BASE_URL=https://api.openai.com/v1 HINDSIGHT_API_LLM_BASE_URL=https://api.openai.com/v1
# API Configuration (Optional) # API Configuration (Optional)

View file

@ -108,6 +108,8 @@ jobs:
HINDSIGHT_API_LLM_API_KEY: ${{ secrets.GROQ_API_KEY }} HINDSIGHT_API_LLM_API_KEY: ${{ secrets.GROQ_API_KEY }}
HINDSIGHT_API_LLM_MODEL: openai/gpt-oss-20b HINDSIGHT_API_LLM_MODEL: openai/gpt-oss-20b
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Prefer CPU-only PyTorch in CI (but keep PyPI for everything else)
UV_INDEX: pytorch=https://download.pytorch.org/whl/cpu
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -132,7 +134,27 @@ jobs:
- name: Install dependencies - name: Install dependencies
working-directory: ./hindsight-api working-directory: ./hindsight-api
run: uv sync --extra test run: uv sync --extra test --no-install-project --index-strategy unsafe-best-match
- name: Cache HuggingFace models
uses: actions/cache@v4
with:
path: ~/.cache/huggingface
key: ${{ runner.os }}-huggingface-${{ hashFiles('hindsight-api/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-huggingface-
- name: Pre-download models
working-directory: ./hindsight-api
run: |
uv run python -c "
from sentence_transformers import SentenceTransformer, CrossEncoder
print('Downloading embedding model...')
SentenceTransformer('BAAI/bge-small-en-v1.5')
print('Downloading cross-encoder model...')
CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2')
print('Models downloaded successfully')
"
- name: Run tests - name: Run tests
working-directory: ./hindsight-api working-directory: ./hindsight-api
@ -146,6 +168,8 @@ jobs:
HINDSIGHT_API_LLM_MODEL: openai/gpt-oss-20b HINDSIGHT_API_LLM_MODEL: openai/gpt-oss-20b
HINDSIGHT_API_URL: http://localhost:8888 HINDSIGHT_API_URL: http://localhost:8888
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Prefer CPU-only PyTorch in CI (but keep PyPI for everything else)
UV_INDEX: pytorch=https://download.pytorch.org/whl/cpu
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -174,11 +198,11 @@ jobs:
- name: Install client test dependencies - name: Install client test dependencies
working-directory: ./hindsight-clients/python working-directory: ./hindsight-clients/python
run: uv sync --extra test run: uv sync --extra test --index-strategy unsafe-best-match
- name: Install API dependencies - name: Install API dependencies
working-directory: ./hindsight-api working-directory: ./hindsight-api
run: uv sync run: uv sync --no-install-project --index-strategy unsafe-best-match
- name: Create .env file - name: Create .env file
run: | run: |
@ -223,6 +247,8 @@ jobs:
HINDSIGHT_API_LLM_MODEL: openai/gpt-oss-20b HINDSIGHT_API_LLM_MODEL: openai/gpt-oss-20b
HINDSIGHT_API_URL: http://localhost:8888 HINDSIGHT_API_URL: http://localhost:8888
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Prefer CPU-only PyTorch in CI (but keep PyPI for everything else)
UV_INDEX: pytorch=https://download.pytorch.org/whl/cpu
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -252,7 +278,7 @@ jobs:
- name: Install API dependencies - name: Install API dependencies
working-directory: ./hindsight-api working-directory: ./hindsight-api
run: uv sync run: uv sync --no-install-project --index-strategy unsafe-best-match
- name: Install TypeScript client dependencies - name: Install TypeScript client dependencies
working-directory: ./hindsight-clients/typescript working-directory: ./hindsight-clients/typescript
@ -305,6 +331,8 @@ jobs:
HINDSIGHT_API_LLM_MODEL: openai/gpt-oss-20b HINDSIGHT_API_LLM_MODEL: openai/gpt-oss-20b
HINDSIGHT_API_URL: http://localhost:8888 HINDSIGHT_API_URL: http://localhost:8888
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Prefer CPU-only PyTorch in CI (but keep PyPI for everything else)
UV_INDEX: pytorch=https://download.pytorch.org/whl/cpu
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -341,7 +369,7 @@ jobs:
- name: Install API dependencies - name: Install API dependencies
working-directory: ./hindsight-api working-directory: ./hindsight-api
run: uv sync run: uv sync --no-install-project --index-strategy unsafe-best-match
- name: Create .env file - name: Create .env file
run: | run: |

View file

@ -147,9 +147,13 @@ RUN mkdir -p /home/hindsight/.hindsight/bin && \
curl -fsSL -o /home/hindsight/.hindsight/bin/pg0 \ curl -fsSL -o /home/hindsight/.hindsight/bin/pg0 \
"https://github.com/vectorize-io/pg0/releases/latest/download/$PG0_BINARY" && \ "https://github.com/vectorize-io/pg0/releases/latest/download/$PG0_BINARY" && \
chmod +x /home/hindsight/.hindsight/bin/pg0 && \ chmod +x /home/hindsight/.hindsight/bin/pg0 && \
ls -lh /home/hindsight/.hindsight/bin/pg0 && \
file /home/hindsight/.hindsight/bin/pg0 && \
ldd /home/hindsight/.hindsight/bin/pg0 2>&1 || true && \
break || (echo "Retry $i failed, waiting..." && sleep 10); \ break || (echo "Retry $i failed, waiting..." && sleep 10); \
done && \ done && \
/home/hindsight/.hindsight/bin/pg0 --version echo "Testing pg0 binary..." && \
/home/hindsight/.hindsight/bin/pg0 --version || (echo "pg0 --version failed with exit code $?"; ldd /home/hindsight/.hindsight/bin/pg0; exit 1)
# Pre-download PostgreSQL binaries # Pre-download PostgreSQL binaries
ENV PG0_HOME=/home/hindsight/.pg0-cache ENV PG0_HOME=/home/hindsight/.pg0-cache
@ -280,9 +284,13 @@ RUN mkdir -p /home/hindsight/.hindsight/bin && \
curl -fsSL -o /home/hindsight/.hindsight/bin/pg0 \ curl -fsSL -o /home/hindsight/.hindsight/bin/pg0 \
"https://github.com/vectorize-io/pg0/releases/latest/download/$PG0_BINARY" && \ "https://github.com/vectorize-io/pg0/releases/latest/download/$PG0_BINARY" && \
chmod +x /home/hindsight/.hindsight/bin/pg0 && \ chmod +x /home/hindsight/.hindsight/bin/pg0 && \
ls -lh /home/hindsight/.hindsight/bin/pg0 && \
file /home/hindsight/.hindsight/bin/pg0 && \
ldd /home/hindsight/.hindsight/bin/pg0 2>&1 || true && \
break || (echo "Retry $i failed, waiting..." && sleep 10); \ break || (echo "Retry $i failed, waiting..." && sleep 10); \
done && \ done && \
/home/hindsight/.hindsight/bin/pg0 --version echo "Testing pg0 binary..." && \
/home/hindsight/.hindsight/bin/pg0 --version || (echo "pg0 --version failed with exit code $?"; ldd /home/hindsight/.hindsight/bin/pg0; exit 1)
# Pre-download PostgreSQL binaries # Pre-download PostgreSQL binaries
ENV PG0_HOME=/home/hindsight/.pg0-cache ENV PG0_HOME=/home/hindsight/.pg0-cache

View file

@ -101,12 +101,7 @@ class LocalSTCrossEncoder(CrossEncoderModel):
) )
logger.info(f"Reranker: initializing local provider with model {self.model_name}") logger.info(f"Reranker: initializing local provider with model {self.model_name}")
# Disable lazy loading (meta tensors) which causes issues with newer transformers/accelerate self._model = CrossEncoder(self.model_name)
# Setting low_cpu_mem_usage=False and device_map=None ensures tensors are fully materialized
self._model = CrossEncoder(
self.model_name,
model_kwargs={"low_cpu_mem_usage": False, "device_map": None},
)
logger.info("Reranker: local provider initialized") logger.info("Reranker: local provider initialized")
def predict(self, pairs: List[Tuple[str, str]]) -> List[float]: def predict(self, pairs: List[Tuple[str, str]]) -> List[float]:

View file

@ -14,7 +14,7 @@ dependencies = [
"openai>=1.0.0", "openai>=1.0.0",
"pydantic>=2.0.0", "pydantic>=2.0.0",
"rich>=13.0.0", "rich>=13.0.0",
"sentence-transformers>=3.0.0", "sentence-transformers>=3.0.0,<3.3.0",
"langchain-text-splitters>=0.3.0", "langchain-text-splitters>=0.3.0",
"fastapi[standard]>=0.120.3", "fastapi[standard]>=0.120.3",
"uvicorn>=0.38.0", "uvicorn>=0.38.0",
@ -24,8 +24,8 @@ dependencies = [
"pgvector>=0.4.1", "pgvector>=0.4.1",
"greenlet>=3.2.4", "greenlet>=3.2.4",
"psycopg2-binary>=2.9.11", "psycopg2-binary>=2.9.11",
"transformers>=4.30.0", "transformers>=4.30.0,<4.46.0",
"torch>=2.0.0", "torch>=2.0.0,<2.6.0",
"tiktoken>=0.12.0", "tiktoken>=0.12.0",
"httpx>=0.27.0", "httpx>=0.27.0",
"fastmcp>=2.0.0", "fastmcp>=2.0.0",

View file

@ -281,7 +281,8 @@ async def test_full_api_workflow(api_client, test_bank_id):
final_banks_data = response.json()["banks"] final_banks_data = response.json()["banks"]
final_banks = [a["bank_id"] for a in final_banks_data] final_banks = [a["bank_id"] for a in final_banks_data]
assert test_bank_id in final_banks assert test_bank_id in final_banks
assert len(final_banks) >= len(initial_banks) + 1 # Don't assert count increases due to parallel test cleanup races
# Just verify our bank exists in the list
# ================================================================ # ================================================================
# 10. Clean Up # 10. Clean Up

View file

@ -239,7 +239,7 @@ class TestEndToEndWorkflow:
bank_id=workflow_bank_id, bank_id=workflow_bank_id,
query="What programming technologies do I use?", query="What programming technologies do I use?",
) )
assert len(search_results) > 0 assert len(search_results.results) > 0
# 4. Generate contextual answer # 4. Generate contextual answer
reflect_response = client.reflect( reflect_response = client.reflect(