From 9479d7da9335fda3dd935f39b5a5b33fcfe0176e Mon Sep 17 00:00:00 2001 From: Roland Tannous Date: Tue, 2 Jun 2026 09:18:37 +0400 Subject: [PATCH] =?UTF-8?q?Studio:=20fix=20CI=20blockers=20=E2=80=94=20fro?= =?UTF-8?q?ntend=20max-tokens=20arity,=20import-hoist=20=5F=5Fall=5F=5F=20?= =?UTF-8?q?re-exports,=20unused=20pytest=20import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/verify_import_hoist.py | 35 +++++++++++++++++++ .../src/features/chat/chat-settings-sheet.tsx | 5 ++- tests/python/test_rag_tool_handler.py | 2 -- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/scripts/verify_import_hoist.py b/scripts/verify_import_hoist.py index 606488cc7f..7d7f7b79ca 100644 --- a/scripts/verify_import_hoist.py +++ b/scripts/verify_import_hoist.py @@ -527,6 +527,38 @@ def _git_show(ref: str, path: str) -> str | None: return None +def _module_all_exports(src: str) -> set[str]: + """Names listed in a module-level ``__all__``. + + A name present in ``__all__`` is a declared public re-export, so it is + "used" even when nothing in the module body loads it (e.g. a package + ``__init__`` that aggregates routers). Such names must not be flagged as + newly-added-unused hoists; a genuinely botched hoist still leaves a dangling + reference, which UNRESOLVED-NEW catches independently. + """ + try: + tree = ast.parse(src) + except SyntaxError: + return set() + exports: set[str] = set() + for node in tree.body: + targets = ( + node.targets + if isinstance(node, ast.Assign) + else [node.target] + if isinstance(node, ast.AnnAssign) + else [] + ) + if not any(isinstance(t, ast.Name) and t.id == "__all__" for t in targets): + continue + value = node.value + if isinstance(value, (ast.List, ast.Tuple)): + for elt in value.elts: + if isinstance(elt, ast.Constant) and isinstance(elt.value, str): + exports.add(elt.value) + return exports + + def compare(before_src: str, after_src: str, path: str) -> list[tuple[str, str]]: """Return list of (severity, message). severity in BLOCKER/WARN/INFO. @@ -554,6 +586,7 @@ def compare(before_src: str, after_src: str, path: str) -> list[tuple[str, str]] before_used = used_targets(a) after_used = used_targets(b) + after_all_exports = _module_all_exports(after_src) before_module_targets: set[str] = set() for tids in a["module_import_targets"].values(): before_module_targets |= tids @@ -582,6 +615,8 @@ def compare(before_src: str, after_src: str, path: str) -> list[tuple[str, str]] for n, tids in b["module_import_targets"].items(): if tids & after_used: continue # resolved by something -> fine + if n in after_all_exports: + continue # declared public re-export (used via __all__) newly_added = bool(tids - before_module_targets) was_used_before = bool(tids & before_used) if newly_added or was_used_before: diff --git a/studio/frontend/src/features/chat/chat-settings-sheet.tsx b/studio/frontend/src/features/chat/chat-settings-sheet.tsx index 05faff0c18..c75dd25db6 100644 --- a/studio/frontend/src/features/chat/chat-settings-sheet.tsx +++ b/studio/frontend/src/features/chat/chat-settings-sheet.tsx @@ -1904,7 +1904,10 @@ export function ChatSettingsPanel({ } max={ isExternalModel - ? getExternalMaxOutputTokens(externalProviderType) + ? getExternalMaxOutputTokens( + externalProviderType, + externalSelection?.modelId, + ) : isGguf && ggufContextLength ? ggufContextLength : 32768 diff --git a/tests/python/test_rag_tool_handler.py b/tests/python/test_rag_tool_handler.py index a8d7cf2354..2af0e97403 100644 --- a/tests/python/test_rag_tool_handler.py +++ b/tests/python/test_rag_tool_handler.py @@ -4,8 +4,6 @@ import sys from pathlib import Path from unittest.mock import patch -import pytest - REPO_ROOT = Path(__file__).resolve().parents[2] STUDIO_BACKEND = REPO_ROOT / "studio" / "backend" if str(STUDIO_BACKEND) not in sys.path: