unsloth/studio/backend/tests
Daniel Han 9b5c94df32
CLI: stop unsloth connect from leaking Studio credentials to unverified servers (#6479)
* CLI: stop `unsloth connect` from leaking Studio credentials to unverified servers

`unsloth connect` (and `unsloth chat`) discovered a Studio base URL from
UNSLOTH_STUDIO_URL or the default localhost port after only an unauthenticated
/api/health probe, then sent credentials to it:

- keyless connect iterated every cached API key and sent each as a bearer token
  to {base}/v1/models, so a malicious or port-preempting endpoint could harvest
  all of them;
- with no cached key it self-issued a Studio JWT and POSTed it to
  {base}/api/auth/api-keys;
- unsloth chat sent the same self-issued JWT to the discovered base.

The key cache was a flat, global list with no binding to a server identity, so a
key minted for one Studio could be replayed to any other.

Changes:

- Scope the agent key cache per base URL so a key is only ever replayed to the
  exact server it was minted for. Pre-scoping flat caches are ignored rather
  than replayed (at most one extra local mint on the next launch).
- Gate every automatic credential flow to loopback bases. A non-loopback
  UNSLOTH_STUDIO_URL now requires an explicit --api-key and nothing is sent
  automatically. SSH-tunnelled Studios that land on 127.0.0.1 keep working.
- Mint the API key locally against the Studio auth DB instead of POSTing a
  self-issued JWT over the network, so no bearer token leaves the process on the
  local path.
- Apply the same loopback gate to connect_studio_server (used by unsloth chat).

Fully closing same-host loopback-port preemption needs a signed /api/health
handshake so the client can verify the server identity before sending anything;
that is tracked as a server-side follow-up.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* CLI: verify Studio server identity before auto-sending credentials

Adds a challenge-response so `unsloth connect` and `unsloth chat` can confirm a
discovered loopback endpoint is really this install's Studio (not a process
that preempted the port) before sending it a cached or freshly minted
credential. This closes the same-host loopback-preemption gap left open by the
previous commit, which could only limit the blast radius.

Server:

- storage.get_or_create_identity_secret(): a dedicated server-wide secret in
  app_secrets (kept separate from the per-user JWT secret), readable only by
  the same OS user.
- storage.compute_identity_proof(nonce) = HMAC-SHA256(identity secret, nonce).
- GET /api/auth/identity?nonce=<base64url>: unauthenticated, returns the proof.
  The nonce is opaque to the server and the proof reveals nothing about the
  secret, so answering is safe.

Client:

- verify_studio_identity(base): sends a fresh 32-byte nonce, recomputes the
  expected HMAC from the local same-user secret, and constant-time compares.
  Fails closed on any error.
- connect._agent_api_key gates the loopback cached-key replay and the local
  mint on it; connect_studio_server (used by unsloth chat) gates the
  self-issued JWT on it.

A server that cannot read this install's secret (a different OS user, or a
remote/fake endpoint) cannot produce a matching proof, so the client refuses
and falls back to an explicit --api-key.

Tests: studio/backend/tests/test_identity.py (proof determinism, secret
persistence and caching, route response and nonce validation) and additions to
test_connect.py (the verify gate refuses when unverified, an explicit key skips
the check, and an end-to-end client plus server handshake against a stub HTTP
server).

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* CLI: mint through the verified server instead of the local auth DB

CodeQL (py/clear-text-storage-sensitive-data) flagged the API key written to
the per-server cache and the agent config files once it was sourced from
storage.create_api_key(); the original HTTP-minted key did not trip the query.

Now that the identity handshake cryptographically confirms the loopback
responder really is this Studio before anything is sent, minting through the
server's /api/auth/api-keys endpoint with a self-issued JWT is safe again and
restores the original, CodeQL-clean data flow. The local-DB mint path is
removed.

The security properties are unchanged: discovery is still loopback-gated and
identity-verified, the key cache is still scoped per server, and a credential
reaches the server only after the handshake has proven its identity. The only
difference from the previous commit is that the self-issued JWT is sent to the
already-verified loopback server rather than the key being minted in-process.

Tests updated to mint through the fake server again.

* CLI: address review feedback on connect credential handling

- Reuse a saved per-server key before the loopback/identity gate. Keys are
  scoped per base URL, so a key the user saved with --api-key for a remote or
  SSH-tunnelled Studio (whose identity secret the local handshake can't match)
  is replayed only to that exact server. The loopback + identity-handshake gate
  now guards just auto-minting (self-issuing a JWT and creating a new key),
  which is the path that needs a cryptographically verified local Studio. Fixes
  keyless reuse being impossible for remote/tunnelled Studios the user had
  saved a key for.

- connect_studio_server (unsloth chat / inference): when the user explicitly set
  UNSLOTH_STUDIO_URL but the server can't be safely attached (non-loopback, or
  identity unverifiable), fail with a clear message instead of silently loading
  the model locally. Opportunistic discovery of the local default still falls
  back to a local load.

- Harden cache parsing: tolerate a corrupt or hand-edited cache where a base
  maps to a non-list (which would otherwise iterate a string into
  single-character "keys"), and read the cache as UTF-8.

Tests updated and added: saved-key replay without the handshake for both local
and remote bases, keyless mint still refused when the loopback server is
unverified, and connect_studio_server erroring on an explicit remote while
falling back locally on default discovery.

* CLI: harden connect handshake against relay and gate cached minted keys

Addresses review feedback on the credential handshake:

- Refuse HTTP redirects on credential-bearing requests (the identity handshake,
  /v1/models, key minting, and the chat HTTP backend). A process squatting the
  discovered port could 302 /api/auth/identity to the real Studio and relay its
  valid proof, or bounce a bearer-token request to another base, and urllib
  follows redirects by default. A shared no-redirect opener now treats any 3xx
  as an error.

- Give cached keys provenance. Keys the user supplied with --api-key are "saved"
  and replay without the handshake (needed for remote or SSH-tunnelled Studios
  whose secret the local handshake can't match). Keys we auto-mint are "minted"
  and replay only after the identity handshake, so a port squatter can't collect
  a previously minted localhost key just by answering the health check. New cache
  shape: servers[base] = {"saved": [...], "minted": [...]}.

Known residual: a different-OS-user process that squats the port and can also
reach a genuine same-secret Studio elsewhere on loopback can still manually relay
the identity challenge. Fully closing that needs the proof bound to the server's
real listening port, or OS-level peer-credential checks; tracked as follow-up. A
same-user attacker is out of scope, since it can already read the 0600 key cache.

Tests: redirect rejection in the handshake, minted-cache requiring the handshake
while saved-cache bypasses it, and the existing suites updated for the new cache
shape. unsloth_cli (206) and test_identity.py (5) pass.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* CLI: keep urllib imports function-local in the no-redirect opener

The repo's import-hoist safety linter (scripts/verify_import_hoist.py) flags
hoisting urllib to module level because it re-points the 'urllib' name in the
pre-existing HttpChatBackend._request scope. Build the no-redirect opener lazily
with function-local urllib imports instead, matching this module's convention,
and restore the local 'import urllib.request' in _request and
verify_studio_identity.

* test(identity): skip route tests when routes.auth import chain is unavailable

The identity route tests build a TestClient from routes.auth, which pulls the
whole routes package (routes/__init__ -> inference -> llama_cpp, ...). In a
minimal test matrix without the heavy backend deps, or when another test in the
same process has already broken that import chain, importing it raised and the
two route tests hard-failed. Skip in that case instead: the proof crypto is
covered by the storage-level tests, and the full backend CI still exercises the
route. No behaviour change where the deps are present (5 passed in isolation).

* test(connect): make connect tests pass on native Windows

unsloth connect supports Windows: --no-launch prints PowerShell ($env:X =
"v" / Remove-Item Env:X) instead of POSIX (export/unset), and the launch
path bridges env into a Windows agent .exe over WSLENV. The tests hardcoded
the POSIX shell forms, so on a real windows-latest runner 12 of them failed on
the assertion string even though every command exited 0.

Add OS-aware assertion helpers (_assert_env_set / _assert_env_unset) that check
the right shell syntax for the host OS, and skip the two WSL-from-Linux shim
tests on native Windows (os.name is 'posix' inside WSL, so that path can't run
there). No change on Linux/macOS (57 passed); the connect command's behaviour
is untouched. Validated on a windows-latest staging runner.

* style(connect): tighten comments in the credential-leak fix

Condense the verbose explanatory comments and multi-line docstrings added by
this PR to one or two lines each, drop a few that just restated the code, and
keep the security rationale where it is load-bearing. Comment/whitespace only;
verified with unslothai/scripts comment_tools.py (check --strip-docstrings:
6/6 'code unchanged'). Tests unchanged: connect 57 passed, identity 5 passed.

* CLI/Studio: harden the identity handshake (review round)

Addresses the latest Codex/Gemini review of the handshake:

- Store the identity secret privately. sqlite3.connect created the auth DB
  world-readable under a 022 umask, so another OS user could read app_secrets
  and forge proofs, defeating the same-user assumption the handshake rests on.
  The auth dir and DB are now restricted to owner-only (0700/0600); the JWT
  secret and password hashes there get the same protection.

- Bind the proof to the server's listening port. The stateless HMAC(secret,
  nonce) was relayable: a process squatting the discovered port could proxy the
  challenge to the real Studio on another port and pass it back. The proof now
  covers the port the server actually listens on (from the socket, never the
  Host header) and the client checks it against the port it connected to, so a
  relayed proof from a different port no longer matches. Closes the manual-relay
  residual left after the redirect fix.

- Cap the identity response read (the server is still unverified at that point)
  and serve the identity route from a sync def so its first-call SQLite read
  runs in the threadpool instead of the event loop.

Tests: port-bound proof + relayed-proof rejection added; identity (5) and
unsloth_cli (58) suites pass. Verified end to end against a real backend
(auth DB owner-only, handshake + mint still succeed).

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* CLI/Studio: bind the identity proof to the connection address, not just port

Follow-up to the port binding from the last review. Binding only to the port
left a cross-address relay: a squatter on a different loopback address but the
same port (for example localhost resolving to a squatter on ::1 while the real
Studio is on 127.0.0.1) could proxy the nonce to the real Studio and pass back
a proof that still matched, since both share the port.

The proof now covers the address and the port the connection landed on:

- Server: takes the address+port from request.scope, which uvicorn populates
  from getsockname, so it is the real local address the client reached even
  when Studio is bound to 0.0.0.0 (verified empirically), never the
  client-controlled Host header.

- Client: resolves the base host to one concrete IP, talks to exactly that IP,
  and binds the proof to (IP, port). A proof relayed from a Studio on a
  different address or port was computed for that other endpoint and no longer
  matches the one the client dialed.

Both sides normalise the address through ipaddress so equivalent forms compare
equal. Together with the private-secret and redirect fixes, this closes the
cross-user loopback relay an attacker can mount without reading the secret.

Tests: proof now bound to host+port; relayed-proof rejection retained; identity
(5) and unsloth_cli (58) suites pass. Verified end to end against a real backend
(handshake + mint still succeed).

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* CLI: pick the loopback address at discovery so localhost does not regress

find_studio_server now resolves a bare localhost base to its concrete loopback
addresses and returns the first that answers /api/health, IPv4 127.0.0.1 first
(where unsloth studio binds by default). The whole flow (health probe, identity
check, credential send) then targets that one address instead of racing
IPv4/IPv6 resolution, where localhost could resolve ::1-first and hide a Studio
bound to 127.0.0.1. A literal IP or remote name is unchanged.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-06-21 21:28:38 -07:00
..
__init__.py Final cleanup 2026-03-12 18:28:04 +00:00
conftest.py Studio: clean-room compact RAG (knowledge bases, hybrid search, fast indexing) (#5910) 2026-06-09 21:17:04 -07:00
test_amd_apu_unified_memory.py Studio: graceful recovery ladder when llama-server hard-crashes at startup (#6291) 2026-06-18 09:07:25 -07:00
test_anthropic_cache_ttl.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_anthropic_citations.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_anthropic_citations_edge.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_anthropic_code_execution.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_anthropic_compaction.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_anthropic_fast_mode_and_refusal.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_anthropic_fast_mode_edge.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_anthropic_messages.py Add API server monitor in Studio (#5558) 2026-06-16 20:26:13 +01:00
test_anthropic_thinking_translation.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_anthropic_tool_versions.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_anthropic_web_fetch.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_api_key_expiry.py Studio: add --secure Cloudflare-only mode and revamp API usage examples (#6300) 2026-06-15 04:18:15 -07:00
test_api_monitor.py Studio: trim serving-log noise and surface llama-server engine stats (#6377) 2026-06-17 05:37:57 -07:00
test_api_perf_serialization.py Studio: serialize non-streaming responses once and pool the proxy client (#6393) 2026-06-17 22:38:02 -07:00
test_apple_gpu_sensors.py Studio: show Apple GPU temperature and power in the GPU monitor (macOS) (#6187) 2026-06-12 01:50:45 -07:00
test_audio_token_detection.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_browse_folders_route.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_bypass_permissions.py Studio: Bypass Permissions (skip confirmation, disable tool sandbox) (#5895) 2026-06-15 04:04:22 -07:00
test_cache_case_resolution.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_cached_gguf_routes.py Studio: hide the llama-server install validation probe from model pickers (#6366) 2026-06-16 05:08:38 -07:00
test_capability_detection.py Harden model fetching (#6391) 2026-06-18 05:39:52 -07:00
test_chat_history_routes.py feat: implement thread forking functionality with associated database… (#5810) 2026-06-15 14:57:39 +01:00
test_chat_history_storage.py feat: implement thread forking functionality with associated database… (#5810) 2026-06-15 14:57:39 +01:00
test_chat_load_during_training.py Studio: free chat model VRAM at training start only when the GPU is tight (#6243) 2026-06-18 09:04:01 -07:00
test_cleanup_cancelled_checkpoints.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_cloudflare_tunnel.py Studio: only advertise a Cloudflare tunnel once it actually serves (#6264) 2026-06-12 14:36:35 -03:00
test_compute_buffer.py studio: deterministic VRAM auto-fit for GGUF (MTP reserve, compute buffer, total-based budget) (#6312) 2026-06-17 03:10:22 -07:00
test_consent_gate.py Harden model fetching (#6391) 2026-06-18 05:39:52 -07:00
test_context_overflow_truncation.py Studio: report the real llama-server context window and add an opt-in overflow policy for OpenAI-compatible serving (#6164) 2026-06-11 07:49:55 -07:00
test_cpu_threads.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_data_recipe_github_progress.py Studio: add github_repo seed reader and GitHub Support Bot recipe (#5169) 2026-04-24 12:02:03 -07:00
test_data_recipe_seed.py fix(seed): disable remote code execution in seed inspect dataset loads (#4275) 2026-03-13 19:37:43 +04:00
test_datacenter_gpu_tuning.py Studio: tune llama.cpp env for data-center GPUs (#6098) 2026-06-12 02:39:01 -07:00
test_dataset_upload_limits.py Formatting: ruff line-length 100, kwarg-spacing passes, drop blank after short local imports (#6079) 2026-06-08 04:24:13 -07:00
test_default_output_dir_name.py Studio: fix training output dir escaping outputs root for models on another drive (#6293) 2026-06-13 04:06:17 -07:00
test_desktop_auth.py Studio: in-app Update llama.cpp button to install the latest prebuilt (#6097) 2026-06-10 10:04:26 -07:00
test_detect_mmproj_file.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_export_absolute_paths.py Studio: scale export GGUF size estimates from the real model size (#6418) 2026-06-18 05:44:17 -07:00
test_export_log_cursor.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_export_size_estimate.py Studio: scale export GGUF size estimates from the real model size (#6418) 2026-06-18 05:44:17 -07:00
test_external_provider_proxy_env.py Studio: ignore unsupported env proxy during Studio startup (#6102) 2026-06-11 05:13:27 -07:00
test_external_provider_usage_chunk.py Studio: Add custom provider option to Connections (#6112) 2026-06-12 13:09:35 +02:00
test_file_security.py Harden model fetching (#6391) 2026-06-18 05:39:52 -07:00
test_frontend_resolution.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_gemini_provider.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_gemma4_chat_template_override.py Studio: bundle Gemma 4 chat templates (E2B/E4B + larger) and auto-apply to unsloth/gemma-4-*-GGUF (#6245) 2026-06-12 05:49:39 -07:00
test_gguf_completion_usage.py Studio: improve OpenAI- and Anthropic-compatible API spec compliance (#6010) 2026-06-09 17:13:25 +02:00
test_gguf_metadata.py Studio: add 'Load on selection' toggle to configure load options before loading (#6348) 2026-06-17 16:24:10 +01:00
test_gguf_reload_inheritance.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_gguf_route_cursor_reset.py Studio: extend llama.cpp first-token timeout (#5841) 2026-06-12 18:41:38 +02:00
test_gguf_routing.py Fix GGUF variant file selection (#6342) 2026-06-16 12:42:58 +02:00
test_gguf_xet_fallback_integration.py Studio: Xet-primary model downloads with automatic HTTP fallback on stall (#6372) 2026-06-16 06:17:54 -07:00
test_gpu_selection.py Studio: free chat model VRAM at training start only when the GPU is tight (#6243) 2026-06-18 09:04:01 -07:00
test_gpu_selection_sandbox.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_hf_xet_fallback.py Studio: Xet-primary model downloads with automatic HTTP fallback on stall (#6372) 2026-06-16 06:17:54 -07:00
test_host_defaults.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_identity.py CLI: stop unsloth connect from leaking Studio credentials to unverified servers (#6479) 2026-06-21 21:28:38 -07:00
test_index_bootstrap_origin.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_index_bootstrap_origin_extra.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_inference_model_validation.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_inference_orchestrator_crash_message.py Studio: fix Gemma-4-12B-it not loading (#6054) 2026-06-10 08:39:07 -07:00
test_install_resolve_prebuilt.py Studio: offer the in-app llama.cpp update for source-build (markerless) installs (#6188) 2026-06-11 02:45:12 -07:00
test_kv_cache_estimation.py studio: deterministic VRAM auto-fit for GGUF (MTP reserve, compute buffer, total-based budget) (#6312) 2026-06-17 03:10:22 -07:00
test_lifespan_shutdown.py Studio: make lifespan shutdown resilient to a dead default executor (#6307) 2026-06-15 22:51:46 -07:00
test_llama_cpp_cache_aware_disk_check.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_llama_cpp_context_fit.py studio: deterministic VRAM auto-fit for GGUF (MTP reserve, compute buffer, total-based budget) (#6312) 2026-06-17 03:10:22 -07:00
test_llama_cpp_freshness.py Studio: stop the llama.cpp update banner flickering and show the download size (#6338) 2026-06-17 21:28:54 -07:00
test_llama_cpp_load_progress.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_llama_cpp_load_progress_live.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_llama_cpp_load_progress_matrix.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_llama_cpp_max_context_threshold.py studio: deterministic VRAM auto-fit for GGUF (MTP reserve, compute buffer, total-based budget) (#6312) 2026-06-17 03:10:22 -07:00
test_llama_cpp_mmproj_fallback.py Studio: graceful recovery ladder when llama-server hard-crashes at startup (#6291) 2026-06-18 09:07:25 -07:00
test_llama_cpp_mtp_detection.py Studio: fix Gemma 4 separate-drafter MTP detection and fallback (#6459) 2026-06-20 04:43:37 -07:00
test_llama_cpp_no_context_shift.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_llama_cpp_props_readback.py Studio: report the real llama-server context window and add an opt-in overflow policy for OpenAI-compatible serving (#6164) 2026-06-11 07:49:55 -07:00
test_llama_cpp_start_failure_classification.py Studio: graceful recovery ladder when llama-server hard-crashes at startup (#6291) 2026-06-18 09:07:25 -07:00
test_llama_cpp_tool_loop.py Rename chat artifacts copy to canvas (#6298) 2026-06-15 13:38:39 +02:00
test_llama_cpp_update.py Tighten comments for PR #6493 (#6539) 2026-06-21 05:49:07 -07:00
test_llama_cpp_wait_for_health.py Windows/WSL installer: fix winget msstore cert failure, amd-smi DiskPart prompt, and enable AMD GPU (Strix Halo gfx1151) (#5940) 2026-06-10 04:24:49 -07:00
test_llama_cpp_wait_for_vram_settle.py Studio: cross-session backstop to reap a leftover llama-server on startup (#6431) 2026-06-18 05:52:18 -07:00
test_llama_cpp_windows_nvidia_path.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_llama_route.py Studio: fix llama.cpp update toast tag and reload hint (#6493) 2026-06-21 05:40:49 -07:00
test_llama_route_timeouts.py Studio: extend llama.cpp first-token timeout (#5841) 2026-06-12 18:41:38 +02:00
test_llama_server_args.py studio: deterministic VRAM auto-fit for GGUF (MTP reserve, compute buffer, total-based budget) (#6312) 2026-06-17 03:10:22 -07:00
test_llama_stats.py Studio: trim serving-log noise and surface llama-server engine stats (#6377) 2026-06-17 05:37:57 -07:00
test_llm_assist_startup_opt_in.py Studio: make Helper LLM startup pre-cache opt in (#6113) 2026-06-09 15:28:34 +02:00
test_log_filter_no_truncation.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_logging_middleware.py Studio: trim serving-log noise and surface llama-server engine stats (#6377) 2026-06-17 05:37:57 -07:00
test_login_rate_limit.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_mcp_config_import.py studio: show MCP "Import config" on the add-server form (#6030) 2026-06-11 16:17:22 +01:00
test_mcp_servers.py Studio: cache MCP tool discovery instead of re-probing every chat send (#5828) 2026-06-12 14:18:06 +01:00
test_mcp_stdio_improvements.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_mcp_stdio_pr5863.py Studio: enable stdio MCP servers on a loopback bind (#6295) 2026-06-15 03:02:32 +01:00
test_middleware.py test: add regression guards for SecurityHeadersMiddleware pure-ASGI (#6424) 2026-06-17 22:53:43 -07:00
test_mlx_inference_backend.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_mlx_training_worker_config.py Studio: improve logging for dynamic transformers version switching (#6108) 2026-06-15 23:31:43 -07:00
test_mmproj_vram_accounting.py Studio: account for mmproj VRAM in GGUF fit budget (#5825) (#5849) 2026-06-12 15:04:08 +01:00
test_models_get_model_config_case_resolution.py Harden model fetching (#6391) 2026-06-18 05:39:52 -07:00
test_mtp_drafter_companion.py Studio: support separate-file MTP GGUF drafters (Gemma 4) (#6125) 2026-06-10 08:45:12 -07:00
test_mtp_mla_target_ctx.py Studio: gate the MTP target-KV reserve to MTP spec mode, not just MLA (#6449) 2026-06-19 05:51:35 -07:00
test_mtp_vram_budget.py Studio: simplify the inference backend (#6490) 2026-06-21 20:01:09 -03:00
test_multimodal_document.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_namespace_shadow_guard_pr6269.py Studio: keep training from failing when a namespace-package shadows unsloth (#6269) 2026-06-15 06:06:48 -07:00
test_native_context_length.py Expose runtime context length for hub models (#6154) 2026-06-11 22:13:53 +03:00
test_offline_gguf_cache_fallback.py Add API server monitor in Studio (#5558) 2026-06-16 20:26:13 +01:00
test_offline_inference_parent.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_openai_citation_markers.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_openai_citation_markers_edge.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_openai_code_execution.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_openai_compaction.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_openai_container_crud.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_openai_image_generation.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_openai_responses_translation.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_openai_tool_passthrough.py Studio: serialize non-streaming responses once and pool the proxy client (#6393) 2026-06-17 22:38:02 -07:00
test_openai_tool_result_fallbacks.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_pricing.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_pricing_edge.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_process_lifetime.py Reap Studio child processes when the parent dies abnormally (#6425) 2026-06-18 05:51:22 -07:00
test_providers_api.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_pytorch_mirror.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_rag_captioning.py Studio: clean-room compact RAG (knowledge bases, hybrid search, fast indexing) (#5910) 2026-06-09 21:17:04 -07:00
test_rag_chunking.py Studio: clean-room compact RAG (knowledge bases, hybrid search, fast indexing) (#5910) 2026-06-09 21:17:04 -07:00
test_rag_embed_llama_server.py Studio: clean-room compact RAG (knowledge bases, hybrid search, fast indexing) (#5910) 2026-06-09 21:17:04 -07:00
test_rag_embeddings.py Studio: clean-room compact RAG (knowledge bases, hybrid search, fast indexing) (#5910) 2026-06-09 21:17:04 -07:00
test_rag_ingestion.py Studio: project sources backed by RAG (#6205) 2026-06-12 15:42:51 +02:00
test_rag_preview.py Studio: clean-room compact RAG (knowledge bases, hybrid search, fast indexing) (#5910) 2026-06-09 21:17:04 -07:00
test_rag_retrieval.py Studio: clean-room compact RAG (knowledge bases, hybrid search, fast indexing) (#5910) 2026-06-09 21:17:04 -07:00
test_rag_store.py Studio: clean-room compact RAG (knowledge bases, hybrid search, fast indexing) (#5910) 2026-06-09 21:17:04 -07:00
test_recommended_folders_permission.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_responses_api.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_responses_tool_passthrough.py Add API server monitor in Studio (#5558) 2026-06-16 20:26:13 +01:00
test_rocm_oom_guard.py Windows/WSL installer: fix winget msstore cert failure, amd-smi DiskPart prompt, and enable AMD GPU (Strix Halo gfx1151) (#5940) 2026-06-10 04:24:49 -07:00
test_s3_dataset.py feat(studio): implement S3 dataset loading (completes #5951) (#6222) 2026-06-12 14:52:04 +02:00
test_safetensors_capability_advertise.py studio: fix two backend CI test failures (capability dict + MTP recovery race) (#6464) 2026-06-19 04:33:52 -07:00
test_safetensors_tool_loop.py Rename chat artifacts copy to canvas (#6298) 2026-06-15 13:38:39 +02:00
test_sandbox_tools.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_secure_tools_execute.py Keep server-side tools enabled under --secure (#6403) 2026-06-18 05:52:40 -07:00
test_secure_tunnel_gate.py Keep server-side tools enabled under --secure (#6403) 2026-06-18 05:52:40 -07:00
test_security_gate_consistency.py Harden model fetching (#6391) 2026-06-18 05:39:52 -07:00
test_server_disk_logging.py Windows/WSL installer: fix winget msstore cert failure, amd-smi DiskPart prompt, and enable AMD GPU (Strix Halo gfx1151) (#5940) 2026-06-10 04:24:49 -07:00
test_sse_streaming_headers.py Studio: simplify the inference backend (#6490) 2026-06-21 20:01:09 -03:00
test_startup_banner_loopback.py Studio: enable stdio MCP servers on a loopback bind (#6295) 2026-06-15 03:02:32 +01:00
test_studio_api.py Studio: Add Tensor-Parallel llama.cpp support (#6040) 2026-06-12 04:00:52 -07:00
test_studio_train_validation.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_tensor_parallel.py Studio: simplify the inference backend (#6490) 2026-06-21 20:01:09 -03:00
test_thinking_parameter.py feat: add Anthropic-compatible thinking parameter (#5856) 2026-06-15 10:35:33 +01:00
test_tool_approvals.py Studio: Add inline confirmation (Allow/Always allow/Deny) for tool calls (#5869) 2026-06-12 10:55:26 +02:00
test_tool_call_parser_strict.py Improve local chat tool call flow (#5962) 2026-06-09 07:28:44 -07:00
test_tool_confirm_loop.py Studio: Bypass Permissions (skip confirmation, disable tool sandbox) (#5895) 2026-06-15 04:04:22 -07:00
test_tool_confirm_stream.py Studio: Add inline confirmation (Allow/Always allow/Deny) for tool calls (#5869) 2026-06-12 10:55:26 +02:00
test_tool_loop_controller.py Rename chat artifacts copy to canvas (#6298) 2026-06-15 13:38:39 +02:00
test_tool_message_empty_content.py Studio: report the real llama-server context window and add an opt-in overflow policy for OpenAI-compatible serving (#6164) 2026-06-11 07:49:55 -07:00
test_tool_policy_gates.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_tool_policy_state.py unsloth run: add --enable-tools/--disable-tools server-side tool policy (#5277) 2026-05-05 12:45:15 +04:00
test_tool_xml_strip.py Improve local chat tool call flow (#5962) 2026-06-09 07:28:44 -07:00
test_torchao_select.py studio: select torchao version from the installed torch (#6400) 2026-06-17 04:09:40 -07:00
test_trained_model_scan.py Harden model fetching (#6391) 2026-06-18 05:39:52 -07:00
test_training_before_spawn.py Studio: free chat model VRAM at training start only when the GPU is tight (#6243) 2026-06-18 09:04:01 -07:00
test_training_history_update.py Studio: Dark theme refactor, right sidebar redesign, and chat UI polish (#5150) 2026-05-07 14:33:31 +04:00
test_training_nan_loss_handling.py fix(studio): surface live step with null loss through the SSE progress stream (#6206) 2026-06-11 07:50:13 -07:00
test_training_preflight.py Studio: fail fast on an invalid first training batch (base VLM empty chat template) (#6358) 2026-06-18 06:36:33 -07:00
test_training_progress_stream_nan.py fix(studio): surface live step with null loss through the SSE progress stream (#6206) 2026-06-11 07:50:13 -07:00
test_training_raw_support.py MLX Training updates (#5656) 2026-06-14 04:58:50 -07:00
test_training_resume.py feat(studio): implement S3 dataset loading (completes #5951) (#6222) 2026-06-12 14:52:04 +02:00
test_training_vram_coexistence.py Studio: free chat model VRAM at training start only when the GPU is tight (#6243) 2026-06-18 09:04:01 -07:00
test_training_worker_flash_attn.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
test_training_xet_fallback.py Studio: Xet-primary model downloads with automatic HTTP fallback on stall (#6372) 2026-06-16 06:17:54 -07:00
test_transformers_version.py Studio: improve logging for dynamic transformers version switching (#6108) 2026-06-15 23:31:43 -07:00
test_utils.py Studio: harden GPU startup detection and clarify multi-GPU listing (#6427) 2026-06-18 02:35:13 -07:00
test_validate_gguf_runtime_message.py Studio: show an actionable message when the GGUF runtime is missing (#6327) 2026-06-18 06:00:00 -07:00
test_validate_model_error.py Harden model fetching (#6391) 2026-06-18 05:39:52 -07:00
test_vision_cache.py Harden model fetching (#6391) 2026-06-18 05:39:52 -07:00
test_vram_estimation.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
test_windows_gpu_detection_mock.py studio: deterministic VRAM auto-fit for GGUF (MTP reserve, compute buffer, total-based budget) (#6312) 2026-06-17 03:10:22 -07:00