Compare commits

...
Sign in to create a new pull request.

4 commits

Author SHA1 Message Date
Daniel Han
da71a695d4 studio: change password setup subtitle wording 2026-03-17 08:13:12 +00:00
Daniel Han
862cbfc302 studio: include reset command in login error message 2026-03-17 08:03:18 +00:00
Daniel Han
3de930ea0b studio: change login error to "Incorrect password", add reset-password CLI
- Login error now says "Incorrect password" instead of the generic
  "Incorrect username or password" since Studio only has one account.
- Add `unsloth studio reset-password` command that deletes the auth
  database so a fresh admin account with a new random password is
  created on the next server start.
2026-03-17 07:56:53 +00:00
Daniel Han
852755cc92 studio: fix stale GGUF metadata when switching models, update default helper model
Reset _supports_reasoning, _supports_tools, _chat_template, and
_context_length at the top of _read_gguf_metadata so flags from a
previously loaded model do not carry over. Without this, loading a
reasoning model (eg Qwen3.5-4B) then switching to a non-reasoning
model (eg Qwen3-4B-Instruct-2507) would keep supports_reasoning=True
from the first model, causing the UI to show "Thought for 0 seconds"
and passing --chat-template-kwargs enable_thinking to a model whose
chat template does not support it.

Also update the default helper GGUF from Qwen3-4B-Instruct-2507-GGUF
to Qwen3.5-4B-GGUF to match the frontend fallback auto-load model.
2026-03-17 07:46:21 +00:00
5 changed files with 36 additions and 4 deletions

View file

@ -178,3 +178,28 @@ def setup():
if result.returncode != 0:
raise typer.Exit(result.returncode)
# ── unsloth studio reset-password ────────────────────────────────────
@studio_app.command("reset-password")
def reset_password():
"""Reset the Studio admin password.
Deletes the auth database so that a fresh admin account with a new
random password is created on the next server start. The Studio
server must be restarted after running this command.
"""
auth_dir = STUDIO_HOME / "auth"
db_file = auth_dir / "auth.db"
pw_file = auth_dir / ".bootstrap_password"
if not db_file.exists():
typer.echo("No auth database found -- nothing to reset.")
raise typer.Exit(0)
db_file.unlink(missing_ok = True)
pw_file.unlink(missing_ok = True)
typer.echo("Auth database deleted. Restart Unsloth Studio to get a new password.")

View file

@ -446,6 +446,13 @@ class LlamaCppBackend:
Parses only the KV pairs we need (~30ms even for multi-GB files).
For split GGUFs, metadata is always in shard 1.
"""
# Reset metadata from any previously loaded model so stale flags
# (eg _supports_reasoning) do not carry over when switching models.
self._context_length = None
self._chat_template = None
self._supports_reasoning = False
self._supports_tools = False
try:
WANTED = {"general.architecture", "tokenizer.chat_template"}
arch = None

View file

@ -54,14 +54,14 @@ async def login(payload: AuthLoginRequest) -> Token:
if record is None:
raise HTTPException(
status_code = status.HTTP_401_UNAUTHORIZED,
detail = "Incorrect username or password",
detail = "Incorrect password. Run 'unsloth studio reset-password' in your terminal to reset it.",
)
salt, pwd_hash, _jwt_secret, must_change_password = record
if not hashing.verify_password(payload.password, salt, pwd_hash):
raise HTTPException(
status_code = status.HTTP_401_UNAUTHORIZED,
detail = "Incorrect username or password",
detail = "Incorrect password. Run 'unsloth studio reset-password' in your terminal to reset it.",
)
access_token = create_access_token(subject = payload.username)

View file

@ -26,7 +26,7 @@ from loggers import get_logger
logger = get_logger(__name__)
DEFAULT_HELPER_MODEL_REPO = "unsloth/Qwen3-4B-Instruct-2507-GGUF"
DEFAULT_HELPER_MODEL_REPO = "unsloth/Qwen3.5-4B-GGUF"
DEFAULT_HELPER_MODEL_VARIANT = "UD-Q4_K_XL"
README_MAX_CHARS = 1500

View file

@ -172,7 +172,7 @@ export function AuthForm({ mode }: AuthFormProps): ReactElement | null {
const title = isLoginMode ? "Welcome back" : "Setup your account";
const subtitle = isLoginMode
? "Sign in with your password."
: "Choose your new password.";
: "Choose a new password";
const submitLabel = isLoginMode ? "Login" : "Change password";
const showSwitchLink = !isLoginMode;
const switchText = "Password already setup? ";