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:
parent
158a6aac9a
commit
d6b7b9b398
7 changed files with 52 additions and 19 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
38
.github/workflows/test.yml
vendored
38
.github/workflows/test.yml
vendored
|
|
@ -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: |
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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]:
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue