88# Set to false when using external providers (TEI, OpenAI, Cohere)
99# PRELOAD_ML_MODELS=true/false - Pre-download ML models during build (default: true)
1010# Only effective when INCLUDE_LOCAL_MODELS=true
11+ # NOTE: tiktoken encodings are ALWAYS preloaded (required for air-gapped deployments)
1112#
1213# Examples:
1314# docker build -t hindsight . # Both (standalone)
@@ -167,6 +168,28 @@ USER hindsight
167168
168169ENV PATH="/app/api/.venv/bin:${PATH}"
169170
171+ # Pre-download tiktoken encoding (ALWAYS - required for token counting even in air-gapped envs)
172+ # Tiktoken is a core runtime dependency, not an optional ML model
173+ RUN MAX_RETRIES=3; \
174+ RETRY_DELAY=5; \
175+ for i in $(seq 1 $MAX_RETRIES); do \
176+ echo "Attempt $i/$MAX_RETRIES: Downloading tiktoken encoding..." ; \
177+ /app/api/.venv/bin/python -c "\
178+ import tiktoken; \
179+ print('Downloading cl100k_base encoding...'); \
180+ tiktoken.get_encoding('cl100k_base'); \
181+ print('Tiktoken encoding cached successfully')" && break; \
182+ if [ $i -lt $MAX_RETRIES ]; then \
183+ echo "Attempt $i failed, retrying in ${RETRY_DELAY}s..." ; \
184+ sleep $RETRY_DELAY; \
185+ RETRY_DELAY=$((RETRY_DELAY * 2)); \
186+ fi; \
187+ done; \
188+ if [ $i -eq $MAX_RETRIES ]; then \
189+ echo "ERROR: Failed to download tiktoken encoding after $MAX_RETRIES attempts" ; \
190+ exit 1; \
191+ fi
192+
170193# Pre-download ML models to avoid runtime download (conditional)
171194# Only runs if both PRELOAD_ML_MODELS=true AND INCLUDE_LOCAL_MODELS=true
172195# Includes retry logic with exponential backoff for transient network failures
@@ -185,7 +208,6 @@ print('Downloading embedding model...'); \
185208SentenceTransformer('BAAI/bge-small-en-v1.5'); \
186209print('Downloading cross-encoder model...'); \
187210CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2'); \
188- print('Downloading tiktoken encoding...'); import tiktoken; tiktoken.get_encoding('cl100k_base'); \
189211print('Models cached successfully')" && break; \
190212 if [ $i -lt $MAX_RETRIES ]; then \
191213 echo "Attempt $i failed, retrying in ${RETRY_DELAY}s..." ; \
@@ -297,6 +319,28 @@ USER hindsight
297319
298320ENV PATH="/app/api/.venv/bin:${PATH}"
299321
322+ # Pre-download tiktoken encoding (ALWAYS - required for token counting even in air-gapped envs)
323+ # Tiktoken is a core runtime dependency, not an optional ML model
324+ RUN MAX_RETRIES=3; \
325+ RETRY_DELAY=5; \
326+ for i in $(seq 1 $MAX_RETRIES); do \
327+ echo "Attempt $i/$MAX_RETRIES: Downloading tiktoken encoding..." ; \
328+ /app/api/.venv/bin/python -c "\
329+ import tiktoken; \
330+ print('Downloading cl100k_base encoding...'); \
331+ tiktoken.get_encoding('cl100k_base'); \
332+ print('Tiktoken encoding cached successfully')" && break; \
333+ if [ $i -lt $MAX_RETRIES ]; then \
334+ echo "Attempt $i failed, retrying in ${RETRY_DELAY}s..." ; \
335+ sleep $RETRY_DELAY; \
336+ RETRY_DELAY=$((RETRY_DELAY * 2)); \
337+ fi; \
338+ done; \
339+ if [ $i -eq $MAX_RETRIES ]; then \
340+ echo "ERROR: Failed to download tiktoken encoding after $MAX_RETRIES attempts" ; \
341+ exit 1; \
342+ fi
343+
300344# Pre-download ML models to avoid runtime download (conditional)
301345# Only runs if both PRELOAD_ML_MODELS=true AND INCLUDE_LOCAL_MODELS=true
302346# Includes retry logic with exponential backoff for transient network failures
@@ -315,7 +359,6 @@ print('Downloading embedding model...'); \
315359SentenceTransformer('BAAI/bge-small-en-v1.5'); \
316360print('Downloading cross-encoder model...'); \
317361CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2'); \
318- print('Downloading tiktoken encoding...'); import tiktoken; tiktoken.get_encoding('cl100k_base'); \
319362print('Models cached successfully')" && break; \
320363 if [ $i -lt $MAX_RETRIES ]; then \
321364 echo "Attempt $i failed, retrying in ${RETRY_DELAY}s..." ; \
0 commit comments