From 1eb15162d943d8767c857ebe13d0a370bdd2e50e Mon Sep 17 00:00:00 2001 From: Lee Jackson <130007945+Imagineer99@users.noreply.github.com> Date: Fri, 19 Jun 2026 13:06:03 +0100 Subject: [PATCH] fix: clean up Studio warning log formatting (#6265) * feat: queue chat prompts during generation * fix: address prompt queue review edge cases * fix: harden queued prompt dispatch * fix: track queued prompt run state by thread * fix: preserve prompt queue ordering * fix: isolate prompt queue on new chat * fix: clean up Studio warning log formatting * Fix export log markup --------- Co-authored-by: wasimysaid --- .../export/components/export-run-panel.tsx | 13 ++---- .../src/features/export/lib/log-style.ts | 40 +++++++++++++++++++ studio/install_python_stack.py | 31 +++++++++++++- 3 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 studio/frontend/src/features/export/lib/log-style.ts diff --git a/studio/frontend/src/features/export/components/export-run-panel.tsx b/studio/frontend/src/features/export/components/export-run-panel.tsx index 9a4f0ee137..ebd35c2158 100644 --- a/studio/frontend/src/features/export/components/export-run-panel.tsx +++ b/studio/frontend/src/features/export/components/export-run-panel.tsx @@ -30,6 +30,7 @@ import { useEffect, useRef, useState } from "react"; import { useShallow } from "zustand/react/shallow"; import { EXPORT_METHODS, type ExportMethod } from "../constants"; import type { ExportLogEntry } from "../api/export-api"; +import { getExportLogLineClass } from "../lib/log-style"; import { selectExportProgressPercent, useExportRuntimeStore, @@ -520,22 +521,16 @@ export function ExportRunPanel(props: ExportRunPanelProps) { ) : ( -
+                  
{run.logLines.map((entry, idx) => (
{formatLogLine(entry)}
))} -
+ )} diff --git a/studio/frontend/src/features/export/lib/log-style.ts b/studio/frontend/src/features/export/lib/log-style.ts new file mode 100644 index 0000000000..f5c057702b --- /dev/null +++ b/studio/frontend/src/features/export/lib/log-style.ts @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0 + +import type { ExportLogEntry } from "../api/export-api"; + +type ExportLogTone = "stdout" | "stderr" | "status" | "warning"; + +const WARNING_LINE_PATTERNS = [ + /Skipping import of cpp extensions due to incompatible torch version/i, + /Please see GitHub issue #2919 for more info/i, + /torch_dtype is deprecated!\s*Use dtype instead!/i, +] as const; + +function isWarningLine(line: string): boolean { + return WARNING_LINE_PATTERNS.some((pattern) => pattern.test(line)); +} + +export function getExportLogTone(entry: ExportLogEntry): ExportLogTone { + if (entry.stream === "status") { + return "status"; + } + if (isWarningLine(entry.line)) { + return "warning"; + } + return entry.stream === "stderr" ? "stderr" : "stdout"; +} + +export function getExportLogLineClass(entry: ExportLogEntry): string { + const tone = getExportLogTone(entry); + if (tone === "stderr") { + return "text-rose-300/90"; + } + if (tone === "status") { + return "text-sky-300/90"; + } + if (tone === "warning") { + return "text-status-warning"; + } + return ""; +} diff --git a/studio/install_python_stack.py b/studio/install_python_stack.py index 36c2bc05b5..b2de6592c8 100644 --- a/studio/install_python_stack.py +++ b/studio/install_python_stack.py @@ -20,6 +20,7 @@ import subprocess import sys import sysconfig import tempfile +import textwrap import urllib.request from pathlib import Path @@ -1401,6 +1402,7 @@ VERBOSE: bool = os.environ.get("UNSLOTH_VERBOSE", "0") == "1" # Update _TOTAL if you add/remove steps in install_python_stack(). _STEP: int = 0 _TOTAL: int = 0 # set at runtime in install_python_stack() based on platform +_PROGRESS_LINE_ACTIVE: bool = False # -- Paths -------------------------------------------------------------- SCRIPT_DIR = Path(__file__).resolve().parent @@ -1486,6 +1488,7 @@ _HAS_COLOR = _stdout_supports_color() # 2-space indent, 15-char label (dim), then value. _LABEL = "deps" _COL = 15 +_INDENT = 2 def _green(msg: str) -> str: @@ -1517,15 +1520,38 @@ def _step( color_fn = None, ) -> None: """Print a single step line in the column format.""" + global _PROGRESS_LINE_ACTIVE if color_fn is None: color_fn = _green padded = label[:_COL] - _safe_print(f" {_dim(padded)}{' ' * (_COL - len(padded))}{color_fn(value)}") + plain_prefix_width = _INDENT + _COL + prefix = f"{' ' * _INDENT}{_dim(padded)}{' ' * (_COL - len(padded))}" + wrap_width = max( + 24, + shutil.get_terminal_size((100, 20)).columns - plain_prefix_width, + ) + lines = textwrap.wrap( + value, + width = wrap_width, + break_long_words = False, + break_on_hyphens = False, + ) or [""] + if _PROGRESS_LINE_ACTIVE and not VERBOSE: + try: + sys.stdout.write("\n") + sys.stdout.flush() + except OSError: + pass + _PROGRESS_LINE_ACTIVE = False + _safe_print(f"{prefix}{color_fn(lines[0])}") + continuation_prefix = " " * plain_prefix_width + for line in lines[1:]: + _safe_print(f"{continuation_prefix}{color_fn(line)}") def _progress(label: str) -> None: """Print an in-place progress bar aligned to the step column layout.""" - global _STEP + global _STEP, _PROGRESS_LINE_ACTIVE _STEP += 1 if VERBOSE: return @@ -1537,6 +1563,7 @@ def _progress(label: str) -> None: try: sys.stdout.write(f"\r {_dim(_LABEL)}{pad}[{bar}] {_STEP:2}/{_TOTAL} {label:<20}{end}") sys.stdout.flush() + _PROGRESS_LINE_ACTIVE = end == "" except OSError: pass