v1.0.4 — close the limitations 1.0.3 listed, and correct the ones it overstated
Browse filesCorrection first: 1.0.3 called every write endpoint and SSE-under-a-real-producer untested. True of its probes, not of the project — the suite already covers both (test_runs_sse.py and a dozen test_coach_*_api.py), and it passed on the refreshed lock. A new module written for those endpoints was deleted once that was checked, rather than shipped as duplicate coverage.
Real gaps closed: the Gradio surface is tested (Blocks tree built, rooms and version parity checked, launched for real under gradio 6.27) and had no coverage at all; the Hub tests no longer trust the environment for the missing-dependency path (they inverted silently once the ui extra brought huggingface-hub in); httpx2 joins the dev group so starlette 1.6 stops deprecating TestClient.
Training path verified under the refreshed lock: dream corpus tokenized, SFT run on CPU (loss 3.938, 512 tokens), a real 22 MB LoRA checkpoint written. 767 pass with the ml extra. ROCm/MI300X, multi-GPU, vLLM serving, full-length runs and the imprint->serve tail remain untested and are named as such.
- docs/CHANGELOG.md +59 -0
- docs/NAV.md +2 -1
- mindxtrain/__init__.py +1 -1
- mindxtrain/ui/app.py +1 -1
- pyproject.toml +4 -1
- tests/test_hf_extension.py +20 -7
- tests/test_ui_app_builds.py +44 -0
- uv.lock +54 -4
|
@@ -6,6 +6,65 @@ project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
| 6 |
|
| 7 |
## [Unreleased]
|
| 8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
## [1.0.3] — 2026-09-15
|
| 10 |
|
| 11 |
### Changed
|
|
|
|
| 6 |
|
| 7 |
## [Unreleased]
|
| 8 |
|
| 9 |
+
## [1.0.4] — 2026-09-16
|
| 10 |
+
|
| 11 |
+
### Added
|
| 12 |
+
|
| 13 |
+
- **The Gradio surface is tested.** `mindxtrain ui` had no coverage at all — gradio is an
|
| 14 |
+
optional extra, so a base install cannot import the module, and every release note listed the
|
| 15 |
+
UI as untested. `tests/test_ui_app_builds.py` constructs the whole Blocks tree (which
|
| 16 |
+
exercises every component definition in `ui/app.py`), checks the rooms the docs promise,
|
| 17 |
+
asserts the surface version matches the package, and confirms the PEP 562 lazy export
|
| 18 |
+
resolves. It skips cleanly where the extra is absent. The UI was also launched for real
|
| 19 |
+
under gradio 6.27.0 and served its page and config.
|
| 20 |
+
|
| 21 |
+
### Fixed
|
| 22 |
+
|
| 23 |
+
- **The Hub tests asserted the missing-dependency path by trusting the environment.** They
|
| 24 |
+
passed on a bare install and inverted silently the moment the `ui` extra arrived, because
|
| 25 |
+
gradio depends on huggingface-hub — three tests failed the first time they met an
|
| 26 |
+
environment that had it. Absence is now *forced* (`sys.modules[name] = None` makes the
|
| 27 |
+
import raise), so the contract holds whatever is installed, and it is verified both ways.
|
| 28 |
+
Introduced in 1.0.2, where the note "tested for real rather than mocked" was true only of a
|
| 29 |
+
bare install.
|
| 30 |
+
|
| 31 |
+
### Changed
|
| 32 |
+
|
| 33 |
+
- **`httpx2` added to the dev group.** starlette 1.6 deprecates driving its `TestClient` with
|
| 34 |
+
`httpx`; 24 test modules use `TestClient`, so the dependency moves rather than the tests.
|
| 35 |
+
The deprecation is gone; the two warnings that remain are upstream typer → click 9.0.
|
| 36 |
+
|
| 37 |
+
### Notes — a correction to v1.0.3, and what is now verified
|
| 38 |
+
|
| 39 |
+
**v1.0.3 overstated its own limitations.** It listed "every write endpoint" and "SSE under a
|
| 40 |
+
real producer" as untested. That was true of the dependency-refresh *probes* run for that
|
| 41 |
+
release; it was **not** true of the project. The suite already covers the coach's write
|
| 42 |
+
endpoints — bench, compile, cost, eval/prompt, modelfile build and create, ollama start and
|
| 43 |
+
stop, boardroom, dojo, datasets, mei promote, classroom, autotune feedback, dcoach, chat
|
| 44 |
+
stream — and SSE under a real producer, in `tests/test_runs_sse.py` and a dozen
|
| 45 |
+
`test_coach_*_api.py` modules, including buffer replay on late subscribe, log-kind filtering,
|
| 46 |
+
ingest and cancel. All of it passed on the refreshed lock. A new test module was written for
|
| 47 |
+
those endpoints before that was checked; every endpoint turned out to be covered already and
|
| 48 |
+
the in-stream error contract already asserted, so it was deleted rather than added as
|
| 49 |
+
duplicate coverage.
|
| 50 |
+
|
| 51 |
+
**The training path is now verified under the refreshed lock** (torch 2.11.0, transformers
|
| 52 |
+
5.8.0, trl 1.3.0, peft 0.19.1, alongside starlette 1.6.0 and the pydantic downgrade). The
|
| 53 |
+
dream-corpus loop was run end to end on CPU — corpus read, tokenized, SFT executed
|
| 54 |
+
(loss 3.938, mean_token_accuracy 0.370, 512 tokens), and a real 22 MB LoRA checkpoint written
|
| 55 |
+
with `adapter_model.safetensors`, `adapter_config.json`, tokenizer and chat template. With the
|
| 56 |
+
ml extra installed the suite is **767 passed** (the two tokenizer tests stop skipping).
|
| 57 |
+
|
| 58 |
+
**Still not tested, and not claimed:**
|
| 59 |
+
|
| 60 |
+
- **MI300X / ROCm, multi-GPU, and vLLM serving.** No such hardware here; the CPU lane is what
|
| 61 |
+
was exercised.
|
| 62 |
+
- **A full-length run.** The shipped 32-sample smoke recipe projects ~70 minutes on this
|
| 63 |
+
shared box (8.7 min/step at 50% CPU), so the loop was closed with a reduced variant — 4
|
| 64 |
+
samples at seq 128, the same code path, fewer tokens. Multi-hour and multi-day behaviour is
|
| 65 |
+
unchanged and unverified here.
|
| 66 |
+
- **The `imprint` → `serve --to ollama` tail**, which needs a running daemon.
|
| 67 |
+
|
| 68 |
## [1.0.3] — 2026-09-15
|
| 69 |
|
| 70 |
### Changed
|
|
@@ -164,8 +164,9 @@ Target metrics + framework comparison.
|
|
| 164 |
- [What's not measured (yet)](benchmarks.md#whats-not-measured-yet)
|
| 165 |
|
| 166 |
### [CHANGELOG](CHANGELOG.md)
|
| 167 |
-
Version history (current: v1.0.
|
| 168 |
- [[Unreleased]](CHANGELOG.md#unreleased)
|
|
|
|
| 169 |
- [[1.0.3] — 2026-09-15](CHANGELOG.md#103--2026-09-15)
|
| 170 |
- [[1.0.2] — 2026-09-15](CHANGELOG.md#102--2026-09-15)
|
| 171 |
- [[1.0.1] — 2026-09-15](CHANGELOG.md#101--2026-09-15)
|
|
|
|
| 164 |
- [What's not measured (yet)](benchmarks.md#whats-not-measured-yet)
|
| 165 |
|
| 166 |
### [CHANGELOG](CHANGELOG.md)
|
| 167 |
+
Version history (current: v1.0.4).
|
| 168 |
- [[Unreleased]](CHANGELOG.md#unreleased)
|
| 169 |
+
- [[1.0.4] — 2026-09-16](CHANGELOG.md#104--2026-09-16)
|
| 170 |
- [[1.0.3] — 2026-09-15](CHANGELOG.md#103--2026-09-15)
|
| 171 |
- [[1.0.2] — 2026-09-15](CHANGELOG.md#102--2026-09-15)
|
| 172 |
- [[1.0.1] — 2026-09-15](CHANGELOG.md#101--2026-09-15)
|
|
@@ -16,4 +16,4 @@ Layout per mindXtrain2.md §Part 4 "Repository layout":
|
|
| 16 |
budget/ psutil-derived ResourceBudget (carry-over from aGLM)
|
| 17 |
"""
|
| 18 |
|
| 19 |
-
__version__ = "1.0.
|
|
|
|
| 16 |
budget/ psutil-derived ResourceBudget (carry-over from aGLM)
|
| 17 |
"""
|
| 18 |
|
| 19 |
+
__version__ = "1.0.4"
|
|
@@ -36,7 +36,7 @@ import gradio as gr
|
|
| 36 |
from .metrics import RunMetrics, parse_log # noqa: F401 (parse_log re-exported for tests)
|
| 37 |
from .theme import CSS, theme
|
| 38 |
|
| 39 |
-
VERSION = "1.0.
|
| 40 |
HOME = Path(os.environ.get("MINDXTRAIN_HOME") or Path(__file__).resolve().parents[2])
|
| 41 |
RECIPES = HOME / "mindxtrain" / "train" / "recipes"
|
| 42 |
TIERS = ["Basic", "Advanced", "Scientific"]
|
|
|
|
| 36 |
from .metrics import RunMetrics, parse_log # noqa: F401 (parse_log re-exported for tests)
|
| 37 |
from .theme import CSS, theme
|
| 38 |
|
| 39 |
+
VERSION = "1.0.4"
|
| 40 |
HOME = Path(os.environ.get("MINDXTRAIN_HOME") or Path(__file__).resolve().parents[2])
|
| 41 |
RECIPES = HOME / "mindxtrain" / "train" / "recipes"
|
| 42 |
TIERS = ["Basic", "Advanced", "Scientific"]
|
|
@@ -1,6 +1,6 @@
|
|
| 1 |
[project]
|
| 2 |
name = "mindxtrain"
|
| 3 |
-
version = "1.0.
|
| 4 |
description = "Production training framework for fine-tuning open-weight LLMs on AMD MI300X and serving them through an OpenAI-compatible API."
|
| 5 |
requires-python = ">=3.12,<3.13"
|
| 6 |
license = { text = "Apache-2.0" }
|
|
@@ -74,6 +74,9 @@ packages = ["mindxtrain"]
|
|
| 74 |
dev = [
|
| 75 |
"pytest>=8.3",
|
| 76 |
"pytest-asyncio>=0.24",
|
|
|
|
|
|
|
|
|
|
| 77 |
"ruff>=0.7",
|
| 78 |
"mypy>=1.13",
|
| 79 |
"types-PyYAML>=6.0",
|
|
|
|
| 1 |
[project]
|
| 2 |
name = "mindxtrain"
|
| 3 |
+
version = "1.0.4"
|
| 4 |
description = "Production training framework for fine-tuning open-weight LLMs on AMD MI300X and serving them through an OpenAI-compatible API."
|
| 5 |
requires-python = ">=3.12,<3.13"
|
| 6 |
license = { text = "Apache-2.0" }
|
|
|
|
| 74 |
dev = [
|
| 75 |
"pytest>=8.3",
|
| 76 |
"pytest-asyncio>=0.24",
|
| 77 |
+
# starlette 1.6 deprecates driving its TestClient with httpx and asks for httpx2.
|
| 78 |
+
# 24 test modules use TestClient, so the dependency moves rather than the tests.
|
| 79 |
+
"httpx2>=2.13",
|
| 80 |
"ruff>=0.7",
|
| 81 |
"mypy>=1.13",
|
| 82 |
"types-PyYAML>=6.0",
|
|
@@ -1,12 +1,15 @@
|
|
| 1 |
"""Units for the Hugging Face extension and its CLI surface.
|
| 2 |
|
| 3 |
-
`huggingface_hub` is an optional extra
|
| 4 |
-
|
| 5 |
-
|
|
|
|
|
|
|
| 6 |
"""
|
| 7 |
|
| 8 |
from __future__ import annotations
|
| 9 |
|
|
|
|
| 10 |
from typing import Any
|
| 11 |
|
| 12 |
import pytest
|
|
@@ -25,6 +28,16 @@ def no_ambient_token(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
| 25 |
monkeypatch.delenv(name, raising=False)
|
| 26 |
|
| 27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
# --- token resolution --------------------------------------------------------------------
|
| 29 |
|
| 30 |
|
|
@@ -47,15 +60,15 @@ def test_no_token_anywhere_is_none() -> None:
|
|
| 47 |
# --- the optional dependency is reported, never raised -----------------------------------
|
| 48 |
|
| 49 |
|
| 50 |
-
def test_missing_dependency_is_a_result_not_an_exception() -> None:
|
| 51 |
-
"""
|
| 52 |
api, err = ext._api("a-token")
|
| 53 |
assert api is None
|
| 54 |
assert err["ok"] is False
|
| 55 |
assert "--extra hf" in err["reason"] # the extra that actually installs it
|
| 56 |
|
| 57 |
|
| 58 |
-
def test_pull_base_reports_the_missing_dependency() -> None:
|
| 59 |
out = ext.pull_base("HuggingFaceTB/SmolLM2-135M")
|
| 60 |
assert out["ok"] is False and "huggingface_hub" in out["reason"]
|
| 61 |
|
|
@@ -129,7 +142,7 @@ def test_every_hf_verb_is_reachable() -> None:
|
|
| 129 |
assert verb in result.stdout
|
| 130 |
|
| 131 |
|
| 132 |
-
def test_failure_exits_nonzero_so_a_script_can_branch() -> None:
|
| 133 |
"""The ascent loop warms a base and checks $? — an `ok:false` that exits 0 would be a trap."""
|
| 134 |
result = runner.invoke(app, ["hf", "whoami"])
|
| 135 |
assert result.exit_code == 1
|
|
|
|
| 1 |
"""Units for the Hugging Face extension and its CLI surface.
|
| 2 |
|
| 3 |
+
`huggingface_hub` is an optional extra, so the missing-dependency path is asserted by FORCING
|
| 4 |
+
its absence (`sys.modules[name] = None` makes `import` raise) rather than by trusting the
|
| 5 |
+
ambient environment. It was trusted once: these tests passed on a bare install and inverted
|
| 6 |
+
silently the moment the `ui` extra arrived, because gradio depends on huggingface-hub.
|
| 7 |
+
Everything else runs against stubs: no token, no network, no Hub.
|
| 8 |
"""
|
| 9 |
|
| 10 |
from __future__ import annotations
|
| 11 |
|
| 12 |
+
import sys
|
| 13 |
from typing import Any
|
| 14 |
|
| 15 |
import pytest
|
|
|
|
| 28 |
monkeypatch.delenv(name, raising=False)
|
| 29 |
|
| 30 |
|
| 31 |
+
@pytest.fixture
|
| 32 |
+
def hub_absent(monkeypatch: pytest.MonkeyPatch) -> None:
|
| 33 |
+
"""Force `import huggingface_hub` to fail, whatever is installed.
|
| 34 |
+
|
| 35 |
+
A `None` entry in `sys.modules` makes the import raise ImportError, so the
|
| 36 |
+
not-installed contract is testable on a machine where the extra IS installed.
|
| 37 |
+
"""
|
| 38 |
+
monkeypatch.setitem(sys.modules, "huggingface_hub", None)
|
| 39 |
+
|
| 40 |
+
|
| 41 |
# --- token resolution --------------------------------------------------------------------
|
| 42 |
|
| 43 |
|
|
|
|
| 60 |
# --- the optional dependency is reported, never raised -----------------------------------
|
| 61 |
|
| 62 |
|
| 63 |
+
def test_missing_dependency_is_a_result_not_an_exception(hub_absent: None) -> None:
|
| 64 |
+
"""A missing optional extra is reported as a result; it must never raise at the caller."""
|
| 65 |
api, err = ext._api("a-token")
|
| 66 |
assert api is None
|
| 67 |
assert err["ok"] is False
|
| 68 |
assert "--extra hf" in err["reason"] # the extra that actually installs it
|
| 69 |
|
| 70 |
|
| 71 |
+
def test_pull_base_reports_the_missing_dependency(hub_absent: None) -> None:
|
| 72 |
out = ext.pull_base("HuggingFaceTB/SmolLM2-135M")
|
| 73 |
assert out["ok"] is False and "huggingface_hub" in out["reason"]
|
| 74 |
|
|
|
|
| 142 |
assert verb in result.stdout
|
| 143 |
|
| 144 |
|
| 145 |
+
def test_failure_exits_nonzero_so_a_script_can_branch(hub_absent: None) -> None:
|
| 146 |
"""The ascent loop warms a base and checks $? — an `ok:false` that exits 0 would be a trap."""
|
| 147 |
result = runner.invoke(app, ["hf", "whoami"])
|
| 148 |
assert result.exit_code == 1
|
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""The Gradio surface: does it actually build?
|
| 2 |
+
|
| 3 |
+
`mindxtrain ui` had no coverage at all — gradio is an optional extra, so a base install
|
| 4 |
+
cannot import the module, and every release note honestly listed the UI as untested. This
|
| 5 |
+
closes that: where the extra IS installed the whole Blocks tree is constructed, which
|
| 6 |
+
exercises every component definition in `ui/app.py`; where it is not, the test skips and the
|
| 7 |
+
lazy-import contract is checked instead.
|
| 8 |
+
"""
|
| 9 |
+
|
| 10 |
+
from __future__ import annotations
|
| 11 |
+
|
| 12 |
+
import pytest
|
| 13 |
+
|
| 14 |
+
gradio = pytest.importorskip("gradio", reason="the `ui` extra is not installed")
|
| 15 |
+
|
| 16 |
+
from mindxtrain import __version__ # noqa: E402
|
| 17 |
+
from mindxtrain.ui import app as ui_app # noqa: E402
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def test_the_ui_builds_without_launching() -> None:
|
| 21 |
+
"""Constructing the Blocks tree is what catches a broken component definition."""
|
| 22 |
+
demo = ui_app.build()
|
| 23 |
+
assert isinstance(demo, gradio.Blocks)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def test_the_ui_reports_the_package_version() -> None:
|
| 27 |
+
"""The surface must not drift from the package it ships with."""
|
| 28 |
+
assert ui_app.VERSION == __version__
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def test_the_rooms_are_present() -> None:
|
| 32 |
+
"""Basic / Advanced / Scientific and the named rooms the docs promise."""
|
| 33 |
+
demo = ui_app.build()
|
| 34 |
+
labels = {getattr(b, "label", None) for b in demo.blocks.values()}
|
| 35 |
+
for room in ("Console · talk to it", "Dataset", "Quantize · CPU", "Science · MEI + research"):
|
| 36 |
+
assert room in labels, f"missing room: {room}"
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def test_build_is_reachable_from_the_package_root() -> None:
|
| 40 |
+
"""The PEP 562 lazy export resolves once gradio is importable."""
|
| 41 |
+
import mindxtrain.ui as ui_pkg
|
| 42 |
+
|
| 43 |
+
assert callable(ui_pkg.build)
|
| 44 |
+
assert ui_pkg.VERSION == __version__
|
|
@@ -1365,6 +1365,19 @@ wheels = [
|
|
| 1365 |
{ url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
|
| 1366 |
]
|
| 1367 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1368 |
[[package]]
|
| 1369 |
name = "httptools"
|
| 1370 |
version = "0.7.1"
|
|
@@ -1404,6 +1417,32 @@ wheels = [
|
|
| 1404 |
{ url = "https://files.pythonhosted.org/packages/d2/fd/6668e5aec43ab844de6fc74927e155a3b37bf40d7c3790e49fc0406b6578/httpx_sse-0.4.3-py3-none-any.whl", hash = "sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc", size = 8960, upload-time = "2025-10-10T21:48:21.158Z" },
|
| 1405 |
]
|
| 1406 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1407 |
[[package]]
|
| 1408 |
name = "huggingface-hub"
|
| 1409 |
version = "1.31.0"
|
|
@@ -1431,11 +1470,11 @@ hf-xet = [
|
|
| 1431 |
|
| 1432 |
[[package]]
|
| 1433 |
name = "idna"
|
| 1434 |
-
version = "3.
|
| 1435 |
source = { registry = "https://pypi.org/simple" }
|
| 1436 |
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
| 1437 |
wheels = [
|
| 1438 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1439 |
]
|
| 1440 |
|
| 1441 |
[[package]]
|
|
@@ -1971,7 +2010,7 @@ wheels = [
|
|
| 1971 |
|
| 1972 |
[[package]]
|
| 1973 |
name = "mindxtrain"
|
| 1974 |
-
version = "1.0.
|
| 1975 |
source = { editable = "." }
|
| 1976 |
dependencies = [
|
| 1977 |
{ name = "blake3" },
|
|
@@ -2051,6 +2090,7 @@ ui = [
|
|
| 2051 |
|
| 2052 |
[package.dev-dependencies]
|
| 2053 |
dev = [
|
|
|
|
| 2054 |
{ name = "mypy" },
|
| 2055 |
{ name = "pytest" },
|
| 2056 |
{ name = "pytest-asyncio" },
|
|
@@ -2097,6 +2137,7 @@ provides-extras = ["ml", "eval", "data", "serve", "ui", "hf", "chain", "obs", "a
|
|
| 2097 |
|
| 2098 |
[package.metadata.requires-dev]
|
| 2099 |
dev = [
|
|
|
|
| 2100 |
{ name = "mypy", specifier = ">=1.13" },
|
| 2101 |
{ name = "pytest", specifier = ">=8.3" },
|
| 2102 |
{ name = "pytest-asyncio", specifier = ">=0.24" },
|
|
@@ -4255,6 +4296,15 @@ wheels = [
|
|
| 4255 |
{ url = "https://files.pythonhosted.org/packages/cf/38/d13f2bc31ce1071eaf519f16f0d2e51d92d08c01895992b05ebe801385d9/trl-1.3.0-py3-none-any.whl", hash = "sha256:55d5bed9983aa3e781c2d0af3b500ea78706247ae7c1852f76ea80417a3f7d5e", size = 721624, upload-time = "2026-04-26T15:28:25.872Z" },
|
| 4256 |
]
|
| 4257 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4258 |
[[package]]
|
| 4259 |
name = "typepy"
|
| 4260 |
version = "1.3.5"
|
|
|
|
| 1365 |
{ url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
|
| 1366 |
]
|
| 1367 |
|
| 1368 |
+
[[package]]
|
| 1369 |
+
name = "httpcore2"
|
| 1370 |
+
version = "2.13.0"
|
| 1371 |
+
source = { registry = "https://pypi.org/simple" }
|
| 1372 |
+
dependencies = [
|
| 1373 |
+
{ name = "h11", marker = "sys_platform != 'emscripten'" },
|
| 1374 |
+
{ name = "truststore", marker = "sys_platform != 'emscripten'" },
|
| 1375 |
+
]
|
| 1376 |
+
sdist = { url = "https://files.pythonhosted.org/packages/15/8c/e925b1c92018abb3a1863ce1549d76d2381e334d21d65d4ac8f65dabd78a/httpcore2-2.13.0.tar.gz", hash = "sha256:2adc8be4fb285fbcd6d894298db3b52c177e74b6674eda3a76bd36be3292a3db", size = 67740, upload-time = "2026-09-14T14:18:04.717Z" }
|
| 1377 |
+
wheels = [
|
| 1378 |
+
{ url = "https://files.pythonhosted.org/packages/7e/0d/117a771a2bb91df334b66bf4da14cd02f21aefbcfe53180f336ce55e8f90/httpcore2-2.13.0-py3-none-any.whl", hash = "sha256:35ae5be347aa40467b4a5dc032ac67ebb6d27189fc97e8cebcf99616f6a1bb9e", size = 83162, upload-time = "2026-09-14T14:18:02.529Z" },
|
| 1379 |
+
]
|
| 1380 |
+
|
| 1381 |
[[package]]
|
| 1382 |
name = "httptools"
|
| 1383 |
version = "0.7.1"
|
|
|
|
| 1417 |
{ url = "https://files.pythonhosted.org/packages/d2/fd/6668e5aec43ab844de6fc74927e155a3b37bf40d7c3790e49fc0406b6578/httpx_sse-0.4.3-py3-none-any.whl", hash = "sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc", size = 8960, upload-time = "2025-10-10T21:48:21.158Z" },
|
| 1418 |
]
|
| 1419 |
|
| 1420 |
+
[[package]]
|
| 1421 |
+
name = "httpx2"
|
| 1422 |
+
version = "2.13.0"
|
| 1423 |
+
source = { registry = "https://pypi.org/simple" }
|
| 1424 |
+
dependencies = [
|
| 1425 |
+
{ name = "anyio", marker = "sys_platform != 'emscripten'" },
|
| 1426 |
+
{ name = "httpcore2", marker = "sys_platform != 'emscripten'" },
|
| 1427 |
+
{ name = "httpx2-jsfetch", marker = "sys_platform == 'emscripten'" },
|
| 1428 |
+
{ name = "idna" },
|
| 1429 |
+
{ name = "truststore", marker = "sys_platform != 'emscripten'" },
|
| 1430 |
+
{ name = "typing-extensions" },
|
| 1431 |
+
]
|
| 1432 |
+
sdist = { url = "https://files.pythonhosted.org/packages/b9/a0/e9deef4654132857b5a5dbe4eddd0ac59c2814500e11f2f5044cd81103ee/httpx2-2.13.0.tar.gz", hash = "sha256:81bd07dc67a3701729ef1f777a3c00c915d4539604fdb5afd327f8682f6b7b44", size = 100290, upload-time = "2026-09-14T14:18:05.486Z" }
|
| 1433 |
+
wheels = [
|
| 1434 |
+
{ url = "https://files.pythonhosted.org/packages/fe/d1/a0c72b0e006df654709fbc366cc5bcb53e5aee13e1e3395152c6dd293376/httpx2-2.13.0-py3-none-any.whl", hash = "sha256:fc12720cedf72faa26cca6b4ca394e05c894e7d7933fc45cafe767960804e49a", size = 95565, upload-time = "2026-09-14T14:18:03.553Z" },
|
| 1435 |
+
]
|
| 1436 |
+
|
| 1437 |
+
[[package]]
|
| 1438 |
+
name = "httpx2-jsfetch"
|
| 1439 |
+
version = "1.0"
|
| 1440 |
+
source = { registry = "https://pypi.org/simple" }
|
| 1441 |
+
sdist = { url = "https://files.pythonhosted.org/packages/cd/c4/0e5636363151a2a1795e0a77617168b9ca438e1748ec05fc9b5687f93d64/httpx2_jsfetch-1.0.tar.gz", hash = "sha256:70a0e3eabfef7cce5ad9c629f7d01ca05e418f586646f4ddf14782e4c1454c60", size = 6872, upload-time = "2026-08-07T00:13:07.492Z" }
|
| 1442 |
+
wheels = [
|
| 1443 |
+
{ url = "https://files.pythonhosted.org/packages/9b/43/832f631d32e4f1211caa2ba368317739fe71f0b8530e4c9d15dc454bac2a/httpx2_jsfetch-1.0-py3-none-any.whl", hash = "sha256:cb916b707601e69a07721aabc8f3f6659be3a6893bc1ff5c6f9e02241df2da32", size = 6382, upload-time = "2026-08-07T00:13:06.567Z" },
|
| 1444 |
+
]
|
| 1445 |
+
|
| 1446 |
[[package]]
|
| 1447 |
name = "huggingface-hub"
|
| 1448 |
version = "1.31.0"
|
|
|
|
| 1470 |
|
| 1471 |
[[package]]
|
| 1472 |
name = "idna"
|
| 1473 |
+
version = "3.19"
|
| 1474 |
source = { registry = "https://pypi.org/simple" }
|
| 1475 |
+
sdist = { url = "https://files.pythonhosted.org/packages/5f/f7/abb373e5757eaec4b922b92f97ec8d6d7e057cf06778247604fbc4e7c3f3/idna-3.19.tar.gz", hash = "sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15", size = 215237, upload-time = "2026-08-18T05:14:24.27Z" }
|
| 1476 |
wheels = [
|
| 1477 |
+
{ url = "https://files.pythonhosted.org/packages/57/b0/0e52c878c53f245edd3a11020f20979b3f490f245af532c7cae3027754b5/idna-3.19-py3-none-any.whl", hash = "sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4", size = 68550, upload-time = "2026-08-18T05:14:22.343Z" },
|
| 1478 |
]
|
| 1479 |
|
| 1480 |
[[package]]
|
|
|
|
| 2010 |
|
| 2011 |
[[package]]
|
| 2012 |
name = "mindxtrain"
|
| 2013 |
+
version = "1.0.4"
|
| 2014 |
source = { editable = "." }
|
| 2015 |
dependencies = [
|
| 2016 |
{ name = "blake3" },
|
|
|
|
| 2090 |
|
| 2091 |
[package.dev-dependencies]
|
| 2092 |
dev = [
|
| 2093 |
+
{ name = "httpx2" },
|
| 2094 |
{ name = "mypy" },
|
| 2095 |
{ name = "pytest" },
|
| 2096 |
{ name = "pytest-asyncio" },
|
|
|
|
| 2137 |
|
| 2138 |
[package.metadata.requires-dev]
|
| 2139 |
dev = [
|
| 2140 |
+
{ name = "httpx2", specifier = ">=2.13" },
|
| 2141 |
{ name = "mypy", specifier = ">=1.13" },
|
| 2142 |
{ name = "pytest", specifier = ">=8.3" },
|
| 2143 |
{ name = "pytest-asyncio", specifier = ">=0.24" },
|
|
|
|
| 4296 |
{ url = "https://files.pythonhosted.org/packages/cf/38/d13f2bc31ce1071eaf519f16f0d2e51d92d08c01895992b05ebe801385d9/trl-1.3.0-py3-none-any.whl", hash = "sha256:55d5bed9983aa3e781c2d0af3b500ea78706247ae7c1852f76ea80417a3f7d5e", size = 721624, upload-time = "2026-04-26T15:28:25.872Z" },
|
| 4297 |
]
|
| 4298 |
|
| 4299 |
+
[[package]]
|
| 4300 |
+
name = "truststore"
|
| 4301 |
+
version = "0.10.4"
|
| 4302 |
+
source = { registry = "https://pypi.org/simple" }
|
| 4303 |
+
sdist = { url = "https://files.pythonhosted.org/packages/53/a3/1585216310e344e8102c22482f6060c7a6ea0322b63e026372e6dcefcfd6/truststore-0.10.4.tar.gz", hash = "sha256:9d91bd436463ad5e4ee4aba766628dd6cd7010cf3e2461756b3303710eebc301", size = 26169, upload-time = "2025-08-12T18:49:02.73Z" }
|
| 4304 |
+
wheels = [
|
| 4305 |
+
{ url = "https://files.pythonhosted.org/packages/19/97/56608b2249fe206a67cd573bc93cd9896e1efb9e98bce9c163bcdc704b88/truststore-0.10.4-py3-none-any.whl", hash = "sha256:adaeaecf1cbb5f4de3b1959b42d41f6fab57b2b1666adb59e89cb0b53361d981", size = 18660, upload-time = "2025-08-12T18:49:01.46Z" },
|
| 4306 |
+
]
|
| 4307 |
+
|
| 4308 |
[[package]]
|
| 4309 |
name = "typepy"
|
| 4310 |
version = "1.3.5"
|