CUDA support - #5
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| pydantic-settings>=2.7 | ||
| aiosqlite>=0.20 | ||
| pathspec>=0.12 | ||
| einops>=0.7 |
There was a problem hiding this comment.
Duplicated requirements file risks silent dependency drift
Medium Severity
requirements-cuda.txt is an exact copy of requirements.txt (all 11 dependency lines are identical). If a future change adds or updates a dependency in one file but not the other, the CUDA image silently breaks. The Dockerfile.cuda could simply COPY api/requirements.txt requirements.txt instead, eliminating the duplicate entirely. Any CUDA-specific packages could be added via a separate RUN pip install step or by using -r requirements.txt inside a minimal CUDA-only file.
Additional Locations (1)
…dule Previous backoff streak retried indefinitely with delay capped at 30m, which meant a permanent GitHub outage produced ~48 polls per day per server. Now a streak gives up after MaxBackoffAttempts (default 5) and the next attempt is anchored to streakStart + Interval — i.e. the regular 6h grid resumes from the FIRST attempt of the failed streak, not from "now". Worst case progression with defaults (Interval=6h, Initial=1m, Max=30m): attempt #1 fails T = 0 attempt #2 fails (wait ~1m) T = +1m attempt #3 fails (wait ~2m) T = +3m attempt #4 fails (wait ~4m) T = +7m attempt #5 fails (wait ~8m) T = +15m → exhaust attempt #6 fires T = T0 + 6h (anchor) Successful poll mid-streak resets attempt counter and wait reverts to Interval. The "anchor from first attempt" choice keeps the long-term schedule on its grid even when a streak ate up to ~30m of it; an absurdly long streak (rare; needs Interval < BackoffMax × N) collapses the wait to 0 and fires immediately, which is the only sensible behaviour when we already overshot. - MaxBackoffAttempts surfaced on Config (default 5). - TestRunStreakExhaustedAnchorsToInterval covers the exhaust path: 3 fails → anchored sleep → #4 fires near streakStart+Interval. - Existing TestRunBacksOffOnFailureThenResets unchanged (recovers after 2 fails, well below the cap). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…projects Two related correctness fixes: 1. POST /git-repos was not transactional — a failed gitrepos insert (e.g. UNIQUE violation under concurrent posts) left an orphan projects row in 'pending' that the dashboard couldn't surface for cleanup. The handler now tracks whether it created the project row and runs a compensating DeleteByHash on gitrepos failure. TestAddGitRepo_ConcurrentDuplicate_NoOrphan asserts the invariant: SELECT COUNT(*) FROM projects WHERE host_path = ? == 1 after two parallel posts. 2. workspaceprojects.Link checked precondition + did INSERT in two separate queries — race window where the project could be deleted between the SELECT and INSERT surfaced as a 500 instead of 404. Rewritten as a single INSERT ... SELECT ... WHERE EXISTS, with a follow-up diagnostic SELECT when RowsAffected == 0 to return the right 404/422 reason. 3. TestDeleteProject_CascadesGitRepoAndMembership now explicitly asserts SELECT COUNT(*) FROM workspace_projects WHERE project_path = ? == 0 (instead of relying on UNIQUE-retry inference). Resolves Fix #5, #6, #15, #16. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…projects Two related correctness fixes: 1. POST /git-repos was not transactional — a failed gitrepos insert (e.g. UNIQUE violation under concurrent posts) left an orphan projects row in 'pending' that the dashboard couldn't surface for cleanup. The handler now tracks whether it created the project row and runs a compensating DeleteByHash on gitrepos failure. TestAddGitRepo_ConcurrentDuplicate_NoOrphan asserts the invariant: SELECT COUNT(*) FROM projects WHERE host_path = ? == 1 after two parallel posts. 2. workspaceprojects.Link checked precondition + did INSERT in two separate queries — race window where the project could be deleted between the SELECT and INSERT surfaced as a 500 instead of 404. Rewritten as a single INSERT ... SELECT ... WHERE EXISTS, with a follow-up diagnostic SELECT when RowsAffected == 0 to return the right 404/422 reason. 3. TestDeleteProject_CascadesGitRepoAndMembership now explicitly asserts SELECT COUNT(*) FROM workspace_projects WHERE project_path = ? == 0 (instead of relying on UNIQUE-retry inference). Resolves Fix #5, #6, #15, #16. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>


Title: Add CUDA GPU support for inference
What
Adds a separate CUDA Docker image that runs embedding inference on NVIDIA GPUs.
Why
CPU inference is significantly slower on large codebases. Servers with NVIDIA GPUs can run inference on GPU automatically — embeddings.py already has CUDA auto-detection in place, it just needed a proper CUDA
image to run in.
How
Published as dvcdsys/code-index:cuda. The CPU image :latest is unchanged.
Type of change
Checklist
Note
Medium Risk
Adds a new CUDA-based container build/deploy path and changes Python dependencies, which could impact runtime packaging and deployment on GPU hosts. Core API logic is mostly unchanged but build/infra changes can break installs if misconfigured.
Overview
Adds an experimental NVIDIA GPU (CUDA) deployment option by introducing a new
api/Dockerfile.cuda,docker-compose.cuda.yml, andportainer-stack-cuda.ymlto run embedding inference on GPUs via the NVIDIA Container Toolkit.Updates the
Makefilewithserver-docker-cudaplus CUDA image build/push targets, and documents host requirements and usage inREADME.md. Also removes unused ONNX-related configuration/dependencies by droppingonnx_model_pathfromapi/app/config.pyand removingoptimum/onnxruntimefromapi/requirements.txt.Written by Cursor Bugbot for commit d725614. This will update automatically on new commits. Configure here.