From fac2dc09b0fdf0c38a81f5bad889d58f6706d672 Mon Sep 17 00:00:00 2001 From: Lee Jackson <130007945+Imagineer99@users.noreply.github.com> Date: Wed, 6 May 2026 12:55:37 +0100 Subject: [PATCH 1/3] fix: restore API and Help menu labels (#5310) --- studio/frontend/src/components/app-sidebar.tsx | 15 +++++++++++---- .../src/features/settings/settings-dialog.tsx | 8 ++++---- .../src/features/settings/tabs/api-keys-tab.tsx | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/studio/frontend/src/components/app-sidebar.tsx b/studio/frontend/src/components/app-sidebar.tsx index 171b4eb92d..13b8adfa48 100644 --- a/studio/frontend/src/components/app-sidebar.tsx +++ b/studio/frontend/src/components/app-sidebar.tsx @@ -37,12 +37,13 @@ import { Delete02Icon, Download03Icon, GemIcon, + Globe02Icon, + HelpCircleIcon, Search01Icon, PowerIcon, PencilEdit02Icon, LayoutAlignLeftIcon, Settings02Icon, - SourceCodeSquareIcon, ZapIcon, } from "@hugeicons/core-free-icons"; import { @@ -527,7 +528,7 @@ export function AppSidebar() {
{displayTitle} - Studio + Unsloth
@@ -548,8 +549,8 @@ export function AppSidebar() { useSettingsDialogStore.getState().openDialog("api-keys")} > - - Developer + + API New @@ -578,6 +579,12 @@ export function AppSidebar() { + useSettingsDialogStore.getState().openDialog("about")} + > + + Help + setShutdownOpen(true)}> Shutdown diff --git a/studio/frontend/src/features/settings/settings-dialog.tsx b/studio/frontend/src/features/settings/settings-dialog.tsx index 376af06e9d..63c0a9d388 100644 --- a/studio/frontend/src/features/settings/settings-dialog.tsx +++ b/studio/frontend/src/features/settings/settings-dialog.tsx @@ -10,11 +10,11 @@ import { import { cn } from "@/lib/utils"; import { Cancel01Icon, + Globe02Icon, + HelpCircleIcon, Message01Icon, PaintBrush02Icon, Settings02Icon, - SourceCodeSquareIcon, - SparklesIcon, UserIcon, } from "@hugeicons/core-free-icons"; import { HugeiconsIcon } from "@hugeicons/react"; @@ -40,8 +40,8 @@ const TABS: TabDef[] = [ { id: "profile", label: "Profile", icon: UserIcon }, { id: "appearance", label: "Appearance", icon: PaintBrush02Icon }, { id: "chat", label: "Chat", icon: Message01Icon }, - { id: "api-keys", label: "Developer", icon: SourceCodeSquareIcon, badge: "New" }, - { id: "about", label: "Help", icon: SparklesIcon }, + { id: "api-keys", label: "API", icon: Globe02Icon, badge: "New" }, + { id: "about", label: "Help", icon: HelpCircleIcon }, ]; function renderTab(tab: SettingsTab) { diff --git a/studio/frontend/src/features/settings/tabs/api-keys-tab.tsx b/studio/frontend/src/features/settings/tabs/api-keys-tab.tsx index 64c6f520c0..ac9ec40543 100644 --- a/studio/frontend/src/features/settings/tabs/api-keys-tab.tsx +++ b/studio/frontend/src/features/settings/tabs/api-keys-tab.tsx @@ -63,7 +63,7 @@ export function ApiKeysTab() { return (
-

Developer

+

API

Access Unsloth programmatically via the OpenAI-compatible API.{" "} Date: Wed, 6 May 2026 22:16:20 +0530 Subject: [PATCH 2/3] [studio]: Fix tool reasoning trace in UI (#5314) * fix thought for 1 second issue * gemini suggesion --- .../src/components/assistant-ui/reasoning.tsx | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/studio/frontend/src/components/assistant-ui/reasoning.tsx b/studio/frontend/src/components/assistant-ui/reasoning.tsx index 387f8cd458..fe913baf2a 100644 --- a/studio/frontend/src/components/assistant-ui/reasoning.tsx +++ b/studio/frontend/src/components/assistant-ui/reasoning.tsx @@ -316,15 +316,28 @@ const ReasoningGroupImpl: ReasoningGroupComponent = ({ if (message.status?.type !== "running") { return false; } - const lastIndex = message.parts.length - 1; - if (lastIndex < 0) { + const parts = message.parts; + const len = parts.length; + if (len === 0) { return false; } - const lastType = message.parts[lastIndex]?.type; - if (lastType !== "reasoning") { + + let groupHasReasoning = false; + for (let i = startIndex; i <= endIndex && i < len; i += 1) { + if (parts[i]?.type === "reasoning") { + groupHasReasoning = true; + break; + } + } + if (!groupHasReasoning) { return false; } - return lastIndex >= startIndex && lastIndex <= endIndex; + for (let i = endIndex + 1; i < len; i += 1) { + if (parts[i]?.type !== "tool-call") { + return false; + } + } + return true; }); const persistedDuration = useAuiState(({ message }) => { From 948ce43584c272be016f6c7210d99a6a0bddc26a Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Thu, 7 May 2026 00:12:09 -0700 Subject: [PATCH 3/3] =?UTF-8?q?fix:=203=20patch=5F*=20helpers=20=E2=80=94?= =?UTF-8?q?=20fast=5Flora=20import,=20sft=5Ftrainer=20Union,=20openenv=20O?= =?UTF-8?q?SError=20(#5319)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: import fast_lora_forward inside patch_fast_lora patch_fast_lora has referenced an unbound `fast_lora_forward` since ddf118a8f (2024-11-21). The function is defined at unsloth/kernels/fast_lora.py:652 and re-exported through unsloth/kernels/__init__.py:45, but it was never imported into unsloth/models/_utils.py, so calling patch_fast_lora() raises NameError: name 'fast_lora_forward' is not defined. The bug went unnoticed because no production code path calls patch_fast_lora() unconditionally. Surfaced by a new CPU-CI check that invokes every zero-arg patch_* helper across unsloth + unsloth_zoo (consolidated-tests-ci.yml on PR #5312). Importing inside the function (rather than at module top) keeps the import surface narrow and avoids a circular-import risk if unsloth.kernels.fast_lora ever needs to import from unsloth.models._utils. * fix: inject typing imports into patch_sft_trainer_tokenizer's exec namespace patch_sft_trainer_tokenizer rewrites the source of TRL's SFTTrainer methods (_prepare_non_packed_dataloader, _prepare_dataset) and re-execs them. With TRL 1.x, those methods carry `Union[...]` type hints in their signatures. The current rewrite only injects identifiers found by `dir(trl.trainer.sft_trainer)` into the exec namespace, which does not include `Union`, so exec(function, ...) raises NameError: name 'Union' is not defined. Fix: import Union, Optional, List, Any, Callable, Tuple, Dict, Iterator inside the function. exec receives `locals()` as its globals dict, so those names are visible to the executed source body. Same pattern as unsloth/models/_utils.py:patch_linear_scaling, which already injects `from typing import Union, Optional, List, Any, Callable, Tuple` into its own exec_code. Surfaced by the consolidated CPU-CI runtime patch_* check on PR #5312 in the matrix cell `transformers>=5,<6 + trl>=1,<2`. * fix: guard openenv_vllm_reload_weights against OSError from inspect.getsource TRL 0.29.1 and the 1.x line ship some openenv helpers as compiled bytecode without accessible source on disk. inspect.getsource(patch_target) raises OSError("could not get source code") in that case, which surfaces as a hard failure in patch_trl_openenv() and aborts the rest of the RL_ADDITIONAL_FUNCTIONS["openenv"] iteration. Wrap the getsource call in a try/except OSError and log a warning instead. The wake_up(tags=...) rewrite is the only thing skipped; the core weight-reload patch path stays functional. Surfaced by the consolidated CPU-CI runtime patch_* check on PR #5312 in matrix cells running TRL 0.29.1 (latest <1.0.0) and TRL 1.3.0 (latest 1.x). The pyproject pin (TRL 0.18.2-0.24.0) still gets source for this function so the original code path runs unchanged there. --- unsloth/models/_utils.py | 1 + unsloth/models/rl_replacements.py | 15 ++++++++++++++- unsloth/tokenizer_utils.py | 6 ++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/unsloth/models/_utils.py b/unsloth/models/_utils.py index 34fec53504..d3eee03325 100644 --- a/unsloth/models/_utils.py +++ b/unsloth/models/_utils.py @@ -2483,6 +2483,7 @@ def patch_tokenizer(model, tokenizer): def patch_fast_lora(): import peft.tuners.lora.bnb + from ..kernels.fast_lora import fast_lora_forward peft.tuners.lora.bnb.Linear4bit.forward = fast_lora_forward diff --git a/unsloth/models/rl_replacements.py b/unsloth/models/rl_replacements.py index 0f10847282..c2be1bf74a 100755 --- a/unsloth/models/rl_replacements.py +++ b/unsloth/models/rl_replacements.py @@ -1780,7 +1780,20 @@ def openenv_vllm_reload_weights(): patch_target_name = "generate_rollout_completions" patch_target = getattr(openenv_utils, patch_target_name) - src = inspect.getsource(patch_target) + # TRL 0.29.1+ ships some openenv helpers as compiled bytecode without + # accessible source on disk; inspect.getsource raises OSError("could + # not get source code") in that case. Skip the source-rewrite patch + # rather than crashing -- the core unsloth weight-reload path stays + # functional, only the wake_up tag rewrite is skipped. + try: + src = inspect.getsource(patch_target) + except OSError as e: + logger.warning( + f"Unsloth: Could not retrieve source for trl openenv " + f"{patch_target_name} ({e}); skipping rewrite. " + f"Weight reload still functional." + ) + return src = textwrap.dedent(src) original_src = src diff --git a/unsloth/tokenizer_utils.py b/unsloth/tokenizer_utils.py index 130894e385..67edc41d52 100644 --- a/unsloth/tokenizer_utils.py +++ b/unsloth/tokenizer_utils.py @@ -1580,6 +1580,12 @@ def patch_sft_trainer_tokenizer(): except: return all_imports = dir(trl.trainer.sft_trainer) + # Make typing names available to the exec'd source bodies. TRL >= 1.x + # type-hints _prepare_dataset / _prepare_non_packed_dataloader with + # `Union[...]` and friends; without these imports in the exec namespace + # those become NameErrors at exec time. Mirrors the pattern used in + # unsloth/models/_utils.py:patch_linear_scaling. + from typing import Union, Optional, List, Any, Callable, Tuple, Dict, Iterator # noqa: F401 for ( function_name,