-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathupdate-webui.bat
More file actions
450 lines (392 loc) · 18.4 KB
/
update-webui.bat
File metadata and controls
450 lines (392 loc) · 18.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ROOT=%~dp0"
if "%ROOT:~-1%"=="\" set "ROOT=%ROOT:~0,-1%"
set "UV_BIN=%ROOT%\.uv\bin\uv.exe"
set "PYTHON_BIN=%ROOT%\.venv\Scripts\python.exe"
set "NODE_VERSION=%CODEX_NODE_VERSION%"
if "%NODE_VERSION%"=="" set "NODE_VERSION=24.13.0"
set "NODEENV_DIR=%ROOT%\.nodeenv"
set "NODE_BIN_PRIMARY=%NODEENV_DIR%\Scripts\node.exe"
set "NODE_BIN_FALLBACK=%NODEENV_DIR%\bin\node.exe"
set "NPM_BIN_PRIMARY=%NODEENV_DIR%\Scripts\npm.cmd"
set "NPM_BIN_FALLBACK=%NODEENV_DIR%\bin\npm.cmd"
set "NODE_BIN="
set "NPM_BIN="
set "INTERFACE_DIR=%ROOT%\apps\interface"
set "PACKAGE_LOCK=%INTERFACE_DIR%\package-lock.json"
set "CODEX_FFMPEG_VERSION=%CODEX_FFMPEG_VERSION%"
if "%CODEX_FFMPEG_VERSION%"=="" set "CODEX_FFMPEG_VERSION=7.0.2"
set "ALLOW_UNTRACKED=0"
:parse_args
if "%~1"=="" goto :args_done
if /I "%~1"=="--help" goto :usage
if /I "%~1"=="-h" goto :usage
if /I "%~1"=="--force" (
set "ALLOW_UNTRACKED=1"
shift
goto :parse_args
)
if /I "%~1"=="-f" (
set "ALLOW_UNTRACKED=1"
shift
goto :parse_args
)
call :die E_BAD_ARGS "Unknown argument '%~1'. Use --help."
exit /b 1
:args_done
call :validate_git_state
if errorlevel 1 exit /b 1
if /I "%ALLOW_UNTRACKED%"=="1" call :log "Force mode enabled: untracked paths are ignored in dirty check."
for /f "usebackq delims=" %%I in (`git -C "%ROOT%" rev-parse HEAD 2^>nul`) do set "HEAD_BEFORE=%%I"
if not defined HEAD_BEFORE call :die E_HEAD_UNRESOLVED "Failed to resolve current HEAD."
if errorlevel 1 exit /b 1
call :log "Fetching upstream refs ..."
git -C "%ROOT%" fetch --prune
if errorlevel 1 call :die E_FETCH_FAILED "git fetch --prune failed."
if errorlevel 1 exit /b 1
set "AHEAD="
set "BEHIND="
for /f "tokens=1,2" %%A in ('git -C "%ROOT%" rev-list --left-right --count HEAD...@{u} 2^>nul') do (
set "AHEAD=%%A"
set "BEHIND=%%B"
)
if not defined AHEAD call :die E_UPSTREAM_COUNT_FAILED "Failed to compute ahead/behind status."
if errorlevel 1 exit /b 1
if not defined BEHIND call :die E_UPSTREAM_COUNT_FAILED "Failed to compute ahead/behind status."
if errorlevel 1 exit /b 1
if %AHEAD% GTR 0 if %BEHIND% GTR 0 call :die E_DIVERGED "Branch diverged from upstream (ahead=%AHEAD%, behind=%BEHIND%). Reconcile manually first."
if errorlevel 1 exit /b 1
if %AHEAD% GTR 0 call :die E_AHEAD_OF_UPSTREAM "Local branch is ahead by %AHEAD% commit(s). Push/rebase before update."
if errorlevel 1 exit /b 1
call :prepare_refresh_requirements
if errorlevel 1 exit /b 1
call :validate_torch_mode_guard
if errorlevel 1 exit /b 1
call :resolve_torch_backend
if errorlevel 1 exit /b 1
call :log "Resolved torch backend extra: %TORCH_BACKEND%"
if %BEHIND% EQU 0 (
call :log "Already up to date. No commits pulled; running environment refresh."
) else (
call :log "Pulling updates (ff-only) ..."
git -C "%ROOT%" pull --ff-only
if errorlevel 1 call :die E_PULL_FAILED "git pull --ff-only failed."
if errorlevel 1 exit /b 1
for /f "usebackq delims=" %%I in (`git -C "%ROOT%" rev-parse HEAD 2^>nul`) do set "HEAD_AFTER=%%I"
if not defined HEAD_AFTER call :die E_HEAD_UNRESOLVED "Failed to resolve HEAD after pull."
if errorlevel 1 exit /b 1
if /I "%HEAD_AFTER%"=="%HEAD_BEFORE%" (
call :log "No commit change after pull. Running environment refresh anyway."
) else (
call :log "Pulled new commits from upstream."
)
)
call :refresh_environment
if errorlevel 1 exit /b 1
call :log "Update completed successfully."
exit /b 0
:usage
echo Usage: update-webui.bat [--force] [--help]
echo.
echo Safe updater for stable-diffusion-webui-codex.
echo.
echo Behavior:
echo - Fail-closed preflight ^(dirty tree, detached HEAD, no upstream, ahead/diverged, git operation in progress^).
echo - No destructive commands ^(no reset/clean/restore/delete of user files^).
echo - Git update only via: fetch --prune ^+ pull --ff-only.
echo - Dependency verification runs on every update attempt after git safety checks.
echo - Environment refresh runs on every update attempt after dependency verification.
echo - Auto-provisions repo-local Node.js/npm when missing via nodeenv.
echo.
echo Policy:
echo - Scope: repo root only ^(no submodule/extension updates^).
echo - --force disables untracked-path preflight checks only; tracked changes still abort and git pull safety still applies.
echo - Ignored paths do not block update ^(P2=B^).
echo - Frontend refresh uses lock-preserving mode: npm ci.
echo.
echo Optional env:
echo CODEX_TORCH_MODE=custom ^(updater aborts before dependency sync to avoid overwriting custom PyTorch installs^)
echo CODEX_TORCH_BACKEND=cpu^|cu126^|cu128^|cu130^|rocm64
echo CODEX_CUDA_VARIANT=12.6^|12.8^|13^|cu126^|cu128^|cu130 ^(validated whenever set; used when CODEX_TORCH_BACKEND is not set^)
echo CODEX_NODE_VERSION=^<version^> ^(default 24.13.0; used for nodeenv auto-provisioning^)
echo CODEX_FFMPEG_VERSION=^<version^> ^(default 7.0.2^)
exit /b 0
:log
echo [update] %~1
exit /b 0
:die
echo [update][%~1] %~2 1>&2
exit /b 1
:validate_git_state
where git >nul 2>nul
if errorlevel 1 call :die E_TOOL_MISSING "Required command 'git' not found."
if errorlevel 1 exit /b 1
set "INSIDE="
for /f "usebackq delims=" %%I in (`git -C "%ROOT%" rev-parse --is-inside-work-tree 2^>nul`) do set "INSIDE=%%I"
if /I not "%INSIDE%"=="true" call :die E_NOT_GIT_REPO "Script root '%ROOT%' is not inside a git worktree."
if errorlevel 1 exit /b 1
for %%I in ("%ROOT%") do set "ROOT_CANON=%%~fI"
set "TOPLEVEL="
for /f "usebackq delims=" %%I in (`git -C "%ROOT%" rev-parse --show-toplevel 2^>nul`) do set "TOPLEVEL=%%~fI"
if not defined TOPLEVEL call :die E_GIT_TOPLEVEL_UNRESOLVED "Failed to resolve git top-level."
if errorlevel 1 exit /b 1
if /I not "%TOPLEVEL%"=="%ROOT_CANON%" call :die E_WRONG_REPO_ROOT "Run updater from repository root '%ROOT_CANON%' only."
if errorlevel 1 exit /b 1
set "BRANCH="
for /f "usebackq delims=" %%I in (`git -C "%ROOT%" symbolic-ref --quiet --short HEAD 2^>nul`) do set "BRANCH=%%I"
if not defined BRANCH call :die E_DETACHED_HEAD "Detached HEAD detected. Checkout a branch and rerun."
if errorlevel 1 exit /b 1
set "UPSTREAM="
for /f "usebackq delims=" %%I in (`git -C "%ROOT%" rev-parse --abbrev-ref --symbolic-full-name "@{u}" 2^>nul`) do set "UPSTREAM=%%I"
if not defined UPSTREAM call :die E_NO_UPSTREAM "No upstream configured for branch '%BRANCH%'."
if errorlevel 1 exit /b 1
set "GIT_DIR_RAW="
for /f "usebackq delims=" %%I in (`git -C "%ROOT%" rev-parse --git-dir 2^>nul`) do set "GIT_DIR_RAW=%%I"
if not defined GIT_DIR_RAW call :die E_GIT_DIR_UNRESOLVED "Failed to resolve git dir."
if errorlevel 1 exit /b 1
set "GIT_DIR=%GIT_DIR_RAW%"
if not "%GIT_DIR_RAW:~0,1%"=="\" if not "%GIT_DIR_RAW:~1,1%"==":" set "GIT_DIR=%ROOT%\%GIT_DIR_RAW%"
if exist "%GIT_DIR%\MERGE_HEAD" call :die E_GIT_MERGE_IN_PROGRESS "Merge in progress. Resolve or abort merge before update."
if errorlevel 1 exit /b 1
if exist "%GIT_DIR%\CHERRY_PICK_HEAD" call :die E_GIT_CHERRY_PICK_IN_PROGRESS "Cherry-pick in progress. Resolve or abort before update."
if errorlevel 1 exit /b 1
if exist "%GIT_DIR%\REVERT_HEAD" call :die E_GIT_REVERT_IN_PROGRESS "Revert in progress. Resolve or abort before update."
if errorlevel 1 exit /b 1
if exist "%GIT_DIR%\rebase-apply\NUL" call :die E_GIT_REBASE_IN_PROGRESS "Rebase in progress. Complete or abort rebase before update."
if errorlevel 1 exit /b 1
if exist "%GIT_DIR%\rebase-merge\NUL" call :die E_GIT_REBASE_IN_PROGRESS "Rebase in progress. Complete or abort rebase before update."
if errorlevel 1 exit /b 1
if exist "%GIT_DIR%\BISECT_LOG" call :die E_GIT_BISECT_IN_PROGRESS "Bisect in progress. Finish bisect before update."
if errorlevel 1 exit /b 1
set "TMP_STATUS=%TEMP%\codex-update-status-%RANDOM%-%RANDOM%.txt"
set "TMP_TRACKED=%TEMP%\codex-update-tracked-%RANDOM%-%RANDOM%.txt"
set "TMP_UNTRACKED=%TEMP%\codex-update-untracked-%RANDOM%-%RANDOM%.txt"
set "STATUS_UNTRACKED_MODE=all"
if /I "%ALLOW_UNTRACKED%"=="1" set "STATUS_UNTRACKED_MODE=no"
git -C "%ROOT%" status --porcelain=v1 --untracked-files=%STATUS_UNTRACKED_MODE% > "%TMP_STATUS%"
if errorlevel 1 (
call :delete_if_exists "%TMP_STATUS%"
call :die E_STATUS_FAILED "Failed to inspect git status."
exit /b 1
)
for %%I in ("%TMP_STATUS%") do set "STATUS_SIZE=%%~zI"
if not defined STATUS_SIZE set "STATUS_SIZE=0"
if %STATUS_SIZE% GTR 0 (
type nul > "%TMP_TRACKED%"
type nul > "%TMP_UNTRACKED%"
findstr /B /C:"?? " "%TMP_STATUS%" > "%TMP_UNTRACKED%" 2>nul
findstr /V /B /C:"?? " "%TMP_STATUS%" > "%TMP_TRACKED%" 2>nul
echo [update][E_WORKTREE_DIRTY] Local changes detected; update aborted to protect your files. 1>&2
call :print_status_section "Tracked changes:" "%TMP_TRACKED%"
if /I "%ALLOW_UNTRACKED%"=="1" (
echo [update][E_WORKTREE_DIRTY] Untracked-path preflight checks were disabled by --force. 1>&2
echo [update][E_WORKTREE_DIRTY] Remediation: commit/stash tracked changes, then rerun. 1>&2
) else (
call :print_status_section "Untracked paths:" "%TMP_UNTRACKED%"
echo [update][E_WORKTREE_DIRTY] Ignored paths are excluded by policy ^(P2=B^). 1>&2
echo [update][E_WORKTREE_DIRTY] Remediation: commit/stash tracked changes and move or remove untracked paths, then rerun. 1>&2
)
call :delete_if_exists "%TMP_STATUS%"
call :delete_if_exists "%TMP_TRACKED%"
call :delete_if_exists "%TMP_UNTRACKED%"
exit /b 1
)
call :delete_if_exists "%TMP_STATUS%"
call :delete_if_exists "%TMP_TRACKED%"
call :delete_if_exists "%TMP_UNTRACKED%"
exit /b 0
:print_status_section
echo [update][E_WORKTREE_DIRTY] %~1 1>&2
for %%I in ("%~2") do set "SECTION_SIZE=%%~zI"
if not defined SECTION_SIZE set "SECTION_SIZE=0"
if %SECTION_SIZE% LEQ 0 (
echo - ^(none^) 1>&2
exit /b 0
)
for /f "usebackq delims=" %%L in ("%~2") do echo - %%L 1>&2
exit /b 0
:delete_if_exists
set "TARGET=%~f1"
if not defined TARGET exit /b 0
for %%I in ("%TARGET%") do (
set "TARGET_NAME=%%~nxI"
set "TARGET_DIR=%%~dpI"
)
set "TEMP_DIR="
for %%I in ("%TEMP%\.") do set "TEMP_DIR=%%~fI"
if not defined TEMP_DIR exit /b 0
if /I not "%TARGET_DIR%"=="%TEMP_DIR%" exit /b 0
echo %TARGET_NAME%| findstr /B /C:"codex-update-" >nul 2>nul
if errorlevel 1 exit /b 0
if exist "%TARGET%" del /q "%TARGET%" >nul 2>nul
exit /b 0
:prepare_refresh_requirements
if not exist "%UV_BIN%" call :die E_UV_MISSING "uv not found at '%UV_BIN%'. Run install-webui.cmd first."
if errorlevel 1 exit /b 1
if not exist "%PYTHON_BIN%" call :die E_PYTHON_MISSING "Python runtime missing at '%PYTHON_BIN%'. Run install-webui.cmd first."
if errorlevel 1 exit /b 1
call :ensure_nodeenv
if errorlevel 1 exit /b 1
if not exist "%NPM_BIN%" call :die E_NPM_MISSING "npm not found after nodeenv provisioning. Checked '%NPM_BIN_PRIMARY%' and '%NPM_BIN_FALLBACK%'."
if errorlevel 1 exit /b 1
if not exist "%PACKAGE_LOCK%" call :die E_NPM_LOCK_MISSING "Lock-preserving update requires '%PACKAGE_LOCK%'."
if errorlevel 1 exit /b 1
exit /b 0
:ensure_nodeenv
set "NODE_BIN="
set "NPM_BIN="
if exist "%NODE_BIN_PRIMARY%" set "NODE_BIN=%NODE_BIN_PRIMARY%"
if exist "%NPM_BIN_PRIMARY%" set "NPM_BIN=%NPM_BIN_PRIMARY%"
if "%NODE_BIN%"=="" if exist "%NODE_BIN_FALLBACK%" set "NODE_BIN=%NODE_BIN_FALLBACK%"
if "%NPM_BIN%"=="" if exist "%NPM_BIN_FALLBACK%" set "NPM_BIN=%NPM_BIN_FALLBACK%"
if not "%NODE_BIN%"=="" if not "%NPM_BIN%"=="" goto :ensure_nodeenv_validate
set "NODEENV_FORCE="
if exist "%NODEENV_DIR%\NUL" (
call :log "nodeenv appears incomplete under %NODEENV_DIR%; attempting repair with Node.js %NODE_VERSION% ..."
set "NODEENV_FORCE=--force"
) else (
call :log "npm missing; installing Node.js %NODE_VERSION% into %NODEENV_DIR% ..."
)
"%UV_BIN%" tool run --from nodeenv nodeenv %NODEENV_FORCE% -n "%NODE_VERSION%" "%NODEENV_DIR%"
if errorlevel 1 call :die E_NODEENV_INSTALL_FAILED "nodeenv install failed while preparing updater prerequisites."
if errorlevel 1 exit /b 1
set "NODE_BIN="
set "NPM_BIN="
if exist "%NODE_BIN_PRIMARY%" set "NODE_BIN=%NODE_BIN_PRIMARY%"
if exist "%NPM_BIN_PRIMARY%" set "NPM_BIN=%NPM_BIN_PRIMARY%"
if "%NODE_BIN%"=="" if exist "%NODE_BIN_FALLBACK%" set "NODE_BIN=%NODE_BIN_FALLBACK%"
if "%NPM_BIN%"=="" if exist "%NPM_BIN_FALLBACK%" set "NPM_BIN=%NPM_BIN_FALLBACK%"
if not "%NODE_BIN%"=="" if not "%NPM_BIN%"=="" goto :ensure_nodeenv_validate
call :die E_NODEENV_INCOMPLETE "nodeenv completed, but node/npm are missing under '%NODEENV_DIR%'."
exit /b 1
:ensure_nodeenv_validate
set "NODE_EXISTING="
for /f "delims=" %%I in ('"%NODE_BIN%" -v 2^>nul') do if not defined NODE_EXISTING set "NODE_EXISTING=%%I"
if not defined NODE_EXISTING goto :ensure_nodeenv_corrupt
set "NODE_EXISTING=%NODE_EXISTING:v=%"
if /I "%NODE_EXISTING%"=="%NODE_VERSION%" exit /b 0
call :die E_NODE_VERSION_MISMATCH "'%NODEENV_DIR%' already contains Node.js %NODE_EXISTING%, but CODEX_NODE_VERSION=%NODE_VERSION%. Set CODEX_NODE_VERSION=%NODE_EXISTING% or recreate '%NODEENV_DIR%'."
exit /b 1
:ensure_nodeenv_corrupt
call :die E_NODEENV_CORRUPT "Found '%NODEENV_DIR%', but node/npm are missing or invalid. Recreate '%NODEENV_DIR%' or run install-webui.cmd."
exit /b 1
:validate_torch_mode_guard
if /I "%CODEX_TORCH_MODE%"=="custom" (
call :die E_CUSTOM_TORCH_MODE_UNSUPPORTED "CODEX_TORCH_MODE=custom is not supported by update-webui.bat. Aborting before dependency sync to avoid overwriting a custom PyTorch install."
exit /b 1
)
exit /b 0
:resolve_torch_backend
set "TORCH_BACKEND="
call :resolve_cuda_variant_override
if errorlevel 1 exit /b 1
if defined CODEX_TORCH_BACKEND (
if /I "%CODEX_TORCH_BACKEND%"=="cpu" set "TORCH_BACKEND=cpu"
if /I "%CODEX_TORCH_BACKEND%"=="cu126" set "TORCH_BACKEND=cu126"
if /I "%CODEX_TORCH_BACKEND%"=="cu128" set "TORCH_BACKEND=cu128"
if /I "%CODEX_TORCH_BACKEND%"=="cu130" set "TORCH_BACKEND=cu130"
if /I "%CODEX_TORCH_BACKEND%"=="rocm64" set "TORCH_BACKEND=rocm64"
if not defined TORCH_BACKEND call :die E_INVALID_TORCH_BACKEND "Invalid CODEX_TORCH_BACKEND='%CODEX_TORCH_BACKEND%'."
if errorlevel 1 exit /b 1
exit /b 0
)
if defined VARIANT_BACKEND (
set "TORCH_BACKEND=%VARIANT_BACKEND%"
exit /b 0
)
for /f "usebackq delims=" %%I in (`"%PYTHON_BIN%" -c "import importlib.util,sys; spec=importlib.util.find_spec('torch'); spec or sys.exit(2); import torch; v=str(getattr(torch,'__version__','')).lower(); m=[('+cu126','cu126'),('+cu128','cu128'),('+cu130','cu130'),('+rocm','rocm64'),('+cpu','cpu')]; r=next((name for token,name in m if token in v),None); tv=getattr(torch,'version',None); cuda=getattr(tv,'cuda',None); hip=getattr(tv,'hip',None); c=str(cuda or ''); p=[x for x in c.split('.') if x.isdigit()]; major=int(p[0]) if p else 0; minor=int(p[1]) if len(p)>1 else 0; r=r or ('rocm64' if hip else None) or ('cu130' if major>=13 else ('cu126' if major==12 and minor<=7 else ('cu128' if major==12 else None))) or 'cpu'; print(r)" 2^>nul`) do set "TORCH_BACKEND=%%I"
if not defined TORCH_BACKEND (
call :resolve_torch_backend_from_system
if errorlevel 1 exit /b 1
)
if not defined TORCH_BACKEND call :die E_TORCH_BACKEND_UNRESOLVED "Could not determine torch backend extra. Set CODEX_TORCH_BACKEND explicitly."
if errorlevel 1 exit /b 1
exit /b 0
:resolve_cuda_variant_override
set "VARIANT_BACKEND="
if "%CODEX_CUDA_VARIANT%"=="" exit /b 0
if /I "%CODEX_CUDA_VARIANT%"=="12.6" set "VARIANT_BACKEND=cu126"
if /I "%CODEX_CUDA_VARIANT%"=="cu126" set "VARIANT_BACKEND=cu126"
if /I "%CODEX_CUDA_VARIANT%"=="12.8" set "VARIANT_BACKEND=cu128"
if /I "%CODEX_CUDA_VARIANT%"=="cu128" set "VARIANT_BACKEND=cu128"
if /I "%CODEX_CUDA_VARIANT%"=="13" set "VARIANT_BACKEND=cu130"
if /I "%CODEX_CUDA_VARIANT%"=="cu130" set "VARIANT_BACKEND=cu130"
if not defined VARIANT_BACKEND call :die E_INVALID_CUDA_VARIANT "Invalid CODEX_CUDA_VARIANT='%CODEX_CUDA_VARIANT%'. Expected 12.6|12.8|13|cu126|cu128|cu130."
if errorlevel 1 exit /b 1
exit /b 0
:resolve_torch_backend_from_system
set "TORCH_BACKEND="
where nvidia-smi >nul 2>nul
if errorlevel 1 (
set "TORCH_BACKEND=cpu"
exit /b 0
)
set "CUDA_VER="
for /f "delims=" %%I in ('nvidia-smi --query-gpu=cuda_version --format=csv,noheader 2^>nul') do if not defined CUDA_VER set "CUDA_VER=%%I"
if not defined CUDA_VER (
set "TORCH_BACKEND=cu128"
exit /b 0
)
set "DRIVER_VER="
for /f "delims=" %%I in ('nvidia-smi --query-gpu=driver_version --format=csv,noheader 2^>nul') do if not defined DRIVER_VER set "DRIVER_VER=%%I"
set "DRIVER_MAJOR="
for /f "tokens=1 delims=." %%a in ("%DRIVER_VER%") do set "DRIVER_MAJOR=%%a"
set "DRIVER_MAJOR_NUM="
if not "%DRIVER_MAJOR%"=="" set /a DRIVER_MAJOR_NUM=%DRIVER_MAJOR% 2>nul
if errorlevel 1 set "DRIVER_MAJOR_NUM="
set "DRIVER_MAJOR_SAFE=0"
set "DRIVER_MAJOR_KNOWN=0"
if not "%DRIVER_MAJOR_NUM%"=="" (
set /a DRIVER_MAJOR_SAFE=%DRIVER_MAJOR_NUM% 2>nul
if not errorlevel 1 set "DRIVER_MAJOR_KNOWN=1"
)
if "%DRIVER_MAJOR_KNOWN%"=="1" if %DRIVER_MAJOR_SAFE% LSS 525 (
set "TORCH_BACKEND=cpu"
exit /b 0
)
set "CUDA_MAJOR="
set "CUDA_MINOR=0"
for /f "tokens=1 delims=." %%a in ("%CUDA_VER%") do set "CUDA_MAJOR=%%a"
for /f "tokens=2 delims=." %%a in ("%CUDA_VER%") do set "CUDA_MINOR=%%a"
if "%CUDA_MINOR%"=="" set "CUDA_MINOR=0"
set /a __cuda_minor_num=%CUDA_MINOR% 2>nul
if errorlevel 1 set "CUDA_MINOR=0"
if "%CUDA_MAJOR%"=="13" (
set "TORCH_BACKEND=cu128"
if %DRIVER_MAJOR_SAFE% GEQ 580 set "TORCH_BACKEND=cu130"
) else if "%CUDA_MAJOR%"=="12" (
if %CUDA_MINOR% LEQ 7 (
set "TORCH_BACKEND=cu126"
) else (
set "TORCH_BACKEND=cu128"
)
) else (
set "TORCH_BACKEND=cu128"
)
exit /b 0
:refresh_environment
set "CODEX_ROOT=%ROOT%"
if defined PYTHONPATH (
set "PYTHONPATH=%ROOT%;%PYTHONPATH%"
) else (
set "PYTHONPATH=%ROOT%"
)
call :log "Refreshing Python dependencies with backend extra '%TORCH_BACKEND%' ..."
"%UV_BIN%" sync --locked --extra "%TORCH_BACKEND%"
if errorlevel 1 call :die E_UV_SYNC_FAILED "uv sync failed."
if errorlevel 1 exit /b 1
call :log "Refreshing runtime assets (ffmpeg/ffprobe + RIFE model) ..."
"%PYTHON_BIN%" -c "import os,sys; from apps.backend.video.runtime_dependencies import ensure_ffmpeg_binaries, ensure_rife_model_file; v=os.environ.get('CODEX_FFMPEG_VERSION') or '7.0.2'; b=ensure_ffmpeg_binaries(version=v); m=ensure_rife_model_file(); print('[update] ffmpeg: ' + str(b['ffmpeg'])); print('[update] ffprobe: ' + str(b['ffprobe'])); print('[update] RIFE model: ' + str(m))"
if errorlevel 1 call :die E_RUNTIME_PROVISION_FAILED "Runtime dependency provisioning failed."
if errorlevel 1 exit /b 1
call :log "Refreshing frontend dependencies with npm ci ..."
pushd "%INTERFACE_DIR%" >nul 2>nul
if errorlevel 1 call :die E_INTERFACE_DIR_MISSING "Interface directory not found: '%INTERFACE_DIR%'."
if errorlevel 1 exit /b 1
"%NPM_BIN%" ci --no-audit --no-fund
set "NPM_EXIT=%ERRORLEVEL%"
popd >nul 2>nul
if not "%NPM_EXIT%"=="0" call :die E_NPM_CI_FAILED "npm ci failed."
if not "%NPM_EXIT%"=="0" exit /b 1
exit /b 0