hte-cli 0.2.11__tar.gz → 0.2.13__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hte_cli-0.2.11 → hte_cli-0.2.13}/PKG-INFO +1 -1
- {hte_cli-0.2.11 → hte_cli-0.2.13}/pyproject.toml +1 -1
- {hte_cli-0.2.11 → hte_cli-0.2.13}/src/hte_cli/cli.py +13 -100
- {hte_cli-0.2.11 → hte_cli-0.2.13}/.gitignore +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/README.md +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/src/hte_cli/__init__.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/src/hte_cli/__main__.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/src/hte_cli/api_client.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/src/hte_cli/config.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/src/hte_cli/errors.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/src/hte_cli/events.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/src/hte_cli/image_utils.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/src/hte_cli/runner.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/src/hte_cli/scorers.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/src/hte_cli/version_check.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/tests/__init__.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/tests/e2e/__init__.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/tests/e2e/automated_runner.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/tests/e2e/conftest.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/tests/e2e/e2e_test.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/tests/e2e/test_benchmark_flows.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/tests/e2e/test_eval_logs.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/tests/e2e/test_infrastructure.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/tests/e2e/test_runtime_imports.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/tests/e2e/test_session_lifecycle.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/tests/e2e/verify_docker_deps.py +0 -0
- {hte_cli-0.2.11 → hte_cli-0.2.13}/uv.lock +0 -0
|
@@ -310,108 +310,21 @@ def session_join(ctx, session_id: str, force_setup: bool):
|
|
|
310
310
|
cached_images.append(img)
|
|
311
311
|
continue
|
|
312
312
|
|
|
313
|
-
# Need to pull - show
|
|
314
|
-
|
|
315
|
-
layer_progress: dict[str, dict] = {} # layer_id -> {current, total, phase}
|
|
316
|
-
last_display = [""]
|
|
317
|
-
|
|
318
|
-
def parse_size(s: str) -> float:
|
|
319
|
-
"""Parse size string like '10.5MB' or '1.2GB' to bytes."""
|
|
320
|
-
if not s:
|
|
321
|
-
return 0
|
|
322
|
-
s = s.strip()
|
|
323
|
-
multipliers = {"B": 1, "KB": 1024, "MB": 1024**2, "GB": 1024**3}
|
|
324
|
-
for suffix, mult in multipliers.items():
|
|
325
|
-
if s.upper().endswith(suffix):
|
|
326
|
-
try:
|
|
327
|
-
return float(s[:-len(suffix)].strip()) * mult
|
|
328
|
-
except ValueError:
|
|
329
|
-
return 0
|
|
330
|
-
try:
|
|
331
|
-
return float(s)
|
|
332
|
-
except ValueError:
|
|
333
|
-
return 0
|
|
334
|
-
|
|
335
|
-
def format_size(b: float) -> str:
|
|
336
|
-
"""Format bytes to human readable."""
|
|
337
|
-
if b >= 1024**3:
|
|
338
|
-
return f"{b/1024**3:.1f}GB"
|
|
339
|
-
elif b >= 1024**2:
|
|
340
|
-
return f"{b/1024**2:.0f}MB"
|
|
341
|
-
elif b >= 1024:
|
|
342
|
-
return f"{b/1024:.0f}KB"
|
|
343
|
-
return f"{b:.0f}B"
|
|
344
|
-
|
|
313
|
+
# Need to pull - show progress
|
|
314
|
+
last_status = ["connecting..."]
|
|
345
315
|
with console.status(f"[yellow]↓[/yellow] {short_name} [dim]connecting...[/dim]") as status:
|
|
346
316
|
def show_progress(image: str, line: str):
|
|
347
|
-
#
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
line,
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
# Check for completed layers
|
|
360
|
-
complete_match = re.search(r"([a-f0-9]+):\s*(Pull complete|Download complete|Already exists)", line)
|
|
361
|
-
if complete_match:
|
|
362
|
-
layer_id = complete_match.group(1)
|
|
363
|
-
if layer_id in layer_progress:
|
|
364
|
-
layer_progress[layer_id]["current"] = layer_progress[layer_id]["total"]
|
|
365
|
-
layer_progress[layer_id]["phase"] = "done"
|
|
366
|
-
|
|
367
|
-
# Track waiting layers
|
|
368
|
-
waiting_match = re.search(r"([a-f0-9]+):\s*Waiting", line)
|
|
369
|
-
if waiting_match:
|
|
370
|
-
layer_id = waiting_match.group(1)
|
|
371
|
-
if layer_id not in layer_progress:
|
|
372
|
-
layer_progress[layer_id] = {"current": 0, "total": 0, "phase": "waiting"}
|
|
373
|
-
|
|
374
|
-
# Aggregate progress
|
|
375
|
-
total_current = sum(lp.get("current", 0) for lp in layer_progress.values())
|
|
376
|
-
total_size = sum(lp.get("total", 0) for lp in layer_progress.values())
|
|
377
|
-
downloading = sum(1 for lp in layer_progress.values() if lp.get("phase") == "Downloading")
|
|
378
|
-
extracting = sum(1 for lp in layer_progress.values() if lp.get("phase") == "Extracting")
|
|
379
|
-
done_layers = sum(1 for lp in layer_progress.values() if lp.get("phase") == "done")
|
|
380
|
-
waiting = sum(1 for lp in layer_progress.values() if lp.get("phase") == "waiting")
|
|
381
|
-
total_layers = len(layer_progress)
|
|
382
|
-
|
|
383
|
-
# Only show size progress if we have meaningful data (>1MB)
|
|
384
|
-
if total_size > 1024 * 1024:
|
|
385
|
-
display = f"{format_size(total_current)}/{format_size(total_size)}"
|
|
386
|
-
if downloading > 0:
|
|
387
|
-
display += f" ({downloading} downloading"
|
|
388
|
-
if extracting > 0:
|
|
389
|
-
display += f", {extracting} extracting"
|
|
390
|
-
display += ")"
|
|
391
|
-
elif extracting > 0:
|
|
392
|
-
display += f" ({extracting} extracting)"
|
|
393
|
-
elif total_layers > 0:
|
|
394
|
-
# Show layer counts instead
|
|
395
|
-
parts = []
|
|
396
|
-
if downloading > 0:
|
|
397
|
-
parts.append(f"{downloading} downloading")
|
|
398
|
-
if extracting > 0:
|
|
399
|
-
parts.append(f"{extracting} extracting")
|
|
400
|
-
if done_layers > 0:
|
|
401
|
-
parts.append(f"{done_layers} done")
|
|
402
|
-
if waiting > 0:
|
|
403
|
-
parts.append(f"{waiting} waiting")
|
|
404
|
-
display = ", ".join(parts) if parts else "starting..."
|
|
405
|
-
elif "Pulling" in line:
|
|
406
|
-
display = "preparing..."
|
|
407
|
-
elif line.strip():
|
|
408
|
-
display = line[:40]
|
|
409
|
-
else:
|
|
410
|
-
return
|
|
411
|
-
|
|
412
|
-
if display != last_display[0]:
|
|
413
|
-
last_display[0] = display
|
|
414
|
-
status.update(f"[yellow]↓[/yellow] {short_name} [dim]{display}[/dim]")
|
|
317
|
+
# Show docker output directly - includes MB progress from PTY
|
|
318
|
+
# Lines look like: "abc123: Downloading 360.9MB/4.075GB"
|
|
319
|
+
if ": " in line:
|
|
320
|
+
parts = line.split(": ", 1)
|
|
321
|
+
if len(parts) == 2:
|
|
322
|
+
layer_id = parts[0][-8:]
|
|
323
|
+
layer_status = parts[1][:45]
|
|
324
|
+
display = f"{layer_id}: {layer_status}"
|
|
325
|
+
if display != last_status[0]:
|
|
326
|
+
last_status[0] = display
|
|
327
|
+
status.update(f"[yellow]↓[/yellow] {short_name} [dim]{display}[/dim]")
|
|
415
328
|
|
|
416
329
|
success = pull_image_with_progress(img, on_progress=show_progress)
|
|
417
330
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|