mirror of
https://github.com/unslothai/unsloth.git
synced 2026-08-15 03:43:55 +00:00
5 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
1daaa5cbb4
|
Let a decode failure degrade instead of escaping a fail-closed helper (#7487)
* Let a decode failure degrade instead of escaping a fail-closed helper Pinning utf-8 makes a read that used to return mojibake on Windows raise instead. 33 of those reads sit under a handler catching OSError or json.JSONDecodeError but not UnicodeDecodeError, which subclasses ValueError, so a corrupt file would now escape a helper written to return a default. Adds UnicodeDecodeError to those tuples only. * Treat an undecodable install lock as stale instead of retrying forever |
||
|
|
3fd948eb95
|
Pin utf-8 on shipping-code text I/O instead of the operator locale (#7486)
* Pin utf-8 on shipping-code text I/O instead of the operator locale 113 read_text/write_text/open call sites across unsloth, studio and unsloth_cli let locale.getencoding() decide the encoding. That is utf-8 on the Linux and macOS runners and cp1252 on a stock Windows install, so the same file decodes differently for a Windows user and silently produces mojibake or raises UnicodeDecodeError. Adds tests/test_runtime_text_encoding.py to keep it that way. It resolves openers through each file's own imports rather than a fixed list of module names, so an aliased tarfile.open or a local from PIL.Image import open is not asked for an encoding it does not take. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Scan tracked files only and resolve the unbound Path calling forms * Honour PEP 263 when scanning sources and migrate a legacy JSONL before appending * Scope guard imports lexically and only migrate a legacy file when it round-trips * Leave a legacy JSONL untouched and resolve path aliases in the foreign-opener check * Tighten comments --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> |
||
|
|
6d8c18cd1a
|
Replace standalone Studio wording with Unsloth (#7221)
* Replace standalone Studio wording with Unsloth Replace the single word Studio with Unsloth wherever it is used as shorthand for Unsloth Studio in docs, CLI output, UI strings, i18n locales, workflow display names, comments and docstrings. Kept unchanged: the full name Unsloth Studio, third party product names (LM Studio, Visual Studio, Mac Studio), feature names (Recipe Studio, Fine-tuning Studio and its translations), and all identifiers such as env vars, commands, paths and filenames. * Address review feedback on the Studio wording rename Use "an" before Unsloth where the rename left the article as "a". Restore the split brand where Unsloth and Studio render as two halves of the full product name: the onboarding sidebar subtitle and the IPv6 localhost warning. Scope two messages to the full name Unsloth Studio where plain Unsloth was misleading: the AMD README bullet and the CLI studio setup error. |
||
|
|
c7c353d740
|
Pin isolated Node.js installer to committed sha256 digests (#6625)
* Pin isolated Node.js installer to committed sha256 digests The isolated Node installer verified each downloaded archive only against SHASUMS256.txt fetched from the same nodejs.org origin as the archive, so a compromised CDN or TLS path could serve a malicious archive plus a matching checksum and gain code execution when the extracted node is run during the npm floor check and version probe. Anchor trust in studio/node_prebuilt_pins.json, a committed manifest of per-arch sha256 digests, and verify archives against it. The default channel installs the pinned version and never fetches the remote SHASUMS. Unpinned lts, latest, or explicit versions fail closed via UnpinnedNodeRefused unless UNSLOTH_NODE_ALLOW_UNVERIFIED=1, and the refusal is not swallowed by the keep-existing-on-transient-failure path. Ship the manifest in package-data. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Address review nits on the pinned Node installer - Drop the unused npm_min_major field from node_prebuilt_pins.json; the floor is the NPM_MIN_MAJOR module constant and the dead field could silently drift. - Reword the unpinned-refusal message so it does not tell a user already on the default to install it, and point the "add a pin" hint at the exact asset. - Decode the opt-in SHASUMS body with errors="replace" so a non-UTF8 response yields a clean PrebuiltFallback instead of an uncaught UnicodeDecodeError. - Tests: assert the refusal message (guards the main() catch order, not just the exit code), cover malformed-manifest parsing, and drive the opt-in remote-SHASUMS path end to end through install_prebuilt. * Tighten comments in the pinned Node installer Collapse multi-line rationale comments to single lines, drop docstrings on the obvious internal helpers (load_pins, pinned_sha256), and shorten the manifest note. Comments/docstrings only; verified code-unchanged via AST comparison. * Address Codex review: verify pins on existing installs; tomllib fallback - existing_install_matches now takes an expected_sha and the short-circuit passes the committed pin, so a version-matching but non-pinned or tampered install (e.g. from the old remote-SHASUMS path) is re-verified instead of kept. An unpinned target without opt-in no longer short-circuits on an existing install; it falls through to the UnpinnedNodeRefused fail-closed path. - The package-data test uses pytest.importorskip(tomllib/tomli) so it does not ModuleNotFoundError on the supported 3.9/3.10 interpreters. * Make the transient-failure keep-existing path pin-aware The previous commit added the pinned-digest check to the existing-install short-circuit but not to the post-download-failure fallback, which still kept any runnable same-version install via existing_install_usable(). A same-version install whose recorded sha256 is not the pin could therefore be kept on a transient download failure, the exact artifact the short-circuit rejects. Refuse to keep a same-version pin-mismatched install there too; a different usable version is still kept for offline resilience. * Bump pinned default Node to the current 24 LTS (24.18.0) Node 24 LTS moved to 24.18.0; since the default channel now resolves straight to the manifest, a frozen 24.17.0 would downgrade fresh installs and make UNSLOTH_NODE_VERSION=lts refuse the current LTS as unpinned. Update default_version and all six per-arch digests (verified against the official SHASUMS256.txt), and point the test INDEX/short-circuit fixtures at the new LTS. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> |
||
|
|
9f39cc2c39
|
Studio: use an isolated Node.js for the frontend build instead of replacing the system Node/npm (#6533)
* Studio: use an isolated Node.js for the frontend build instead of replacing the system Node/npm * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Studio: address Node isolation review (no-Node probe crash, PATH refresh, OXC provisioning, venv python, runtime node resolver) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix/adjust Node isolation for PR #6533 * Studio Node: don't cache a negative node resolution; accept Node metadata in setup.sh ownership guard - node_runtime: memoize only a version-adequate executable so a Node installed by a separate-process 'studio update' is picked up without a backend restart. - setup.sh: _studio_owned_adoptable also accepts UNSLOTH_NODE_PREBUILT_INFO.json, matching the setup.ps1 Node ownership guard (custom-home parity). * Studio setup.ps1: skip OXC npm install gracefully when npm is absent Mirror setup.sh's `command -v npm` guard so a pip-installed Studio with no system Node skips the OXC runtime install (validator degrades at runtime) instead of exit 1 aborting the whole setup. Tighten test_node_probe_guard.ps1's probe regex so it only matches the two system-version probes, not this new npm guard. * Wire test_node_probe_guard.ps1 into Windows CI for PR #6533 * Harden isolated Node install and probes for PR #6533 - install_node_prebuilt.py: keep an existing, still-usable isolated Node when nodejs.org's dist index is unreachable instead of aborting the update on a transient outage (existing_install_usable + tolerant fetch). - install_node_prebuilt.py: pin NPM_CONFIG_PREFIX/npm_config_prefix and drop NODE_PATH in _run_node so any npm -g stays inside the isolated prefix; Windows npm otherwise writes to %APPDATA%\npm. - install_node_prebuilt.py: resolve tar hard-link targets against the archive root (symlink targets stay link-parent relative). - setup.ps1: wrap the system node/npm probes in try/catch so a present but broken shim degrades to the bundled Node instead of aborting setup. - setup.ps1: run the isolated Node install with the handed-off/venv Python (ReusedSetupPython); the main resolver runs later and bare python may be a Store stub this early. - setup.sh: log when the OXC validator runtime is skipped for missing npm, matching setup.ps1. - node_runtime.py: move the version-floor comment onto _version_meets_floor. - Tests for the offline-reuse and broken-shim paths. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Trim verbose comments across the Studio Node installer for PR #6533 Comments-only pass: collapse the multi-line section banners to single lines, drop comments that restate obvious code, and tighten the remaining docstrings and "why" notes without losing intent. No code changes (verified with an AST comment-only check on the Python files and a non-comment-diff scan on setup.sh and setup.ps1). Net 109 fewer lines; the install, decision, and probe-guard suites stay green. * Harden Node install from review: validated Python, version floor, legacy home, lock race For PR #6533, addressing the latest review pass: - setup.ps1: run the isolated Node install with the validated reused/venv Python. An incompatible reused interpreter (old venv, conda, stale UNSLOTH_SETUP_PYTHON) is no longer used; fall back to the resolved python instead. - setup.ps1: a STUDIO_HOME/UNSLOTH_STUDIO_HOME override equal to the legacy default now uses the legacy sibling node dir (~/.unsloth/node), matching the runtime resolver and setup.sh, so OXC can find the Node it installed. - install_node_prebuilt.py: reject an explicit --node-version below the floor (^20.19 || >=22.12 || >=23) instead of installing a Node the build cannot use. - install_node_prebuilt.py: atomically rename a stale install lock before unlinking so two concurrent runs without filelock cannot both acquire it. Tests added for the version floor (parametrized + explicit-below-floor rejection). Full install suite: 937 passed, 1 skipped; setup.ps1 parses; decision tests green. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Address latest review: armv7l + later-fetch offline reuse for PR #6533 - install_node_prebuilt.py: reject 32-bit ARM (armv7l) up front. Node 24 LTS ships no linux-armv7l build, so the old path failed late with a confusing "no sha256"; it now fails fast with a clear unsupported-architecture error. - install_node_prebuilt.py: extend the offline-reuse fallback to the SHASUMS and archive fetches. If index.json resolves a newer Node but a later download fails and a usable isolated Node is already on disk, keep it instead of aborting a non-force update. Tests added: armv7l/armhf are unsupported; a SHASUMS failure keeps an existing usable Node and re-raises when none is present. Full install suite: 941 passed. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add UNSLOTH_STUDIO_HOME node-dir tests (install side + resolver) for PR #6533 * Add regression tests pinning the reuse path read-only and isolating installer writes Lock in the two invariants behind the isolated-Node design: reusing a good system Node never mutates the user's Node/npm, and the installer's own npm calls only ever write inside its install_dir. - tests/studio/install/test_install_node_prebuilt_logic.py: assert _run_node redirects NPM_CONFIG_PREFIX/npm_config_prefix into install_dir and drops an inherited NODE_PATH; assert _ensure_npm_floor scopes the npm self-upgrade to install_dir (never -g against the system) and is a no-op once npm meets the floor. - tests/sh/test_system_node_readonly.sh (new, wired into studio-backend-ci.yml): the setup.sh NODE_SOURCE=system arm runs no global install and sets no NPM_CONFIG_PREFIX, with a positive control that the bundled arm does. - tests/studio/test_node_decision.ps1: symmetric structural guard that the prefix pin and the only global install (bun) live in the bundled branch, not the system arm. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: wasimysaid <wasimysdev@gmail.com> |