From 3a407ce038debebee11a54c8df82b5e734760660 Mon Sep 17 00:00:00 2001 From: Ahmed Allam Date: Mon, 27 Jul 2026 23:17:51 +0000 Subject: [PATCH] =?UTF-8?q?perf(cli):=20simplify=20=E2=80=94=20drop=20cons?= =?UTF-8?q?tants=20module=20and=20extra=20lazy-import=20refactors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- strix/core/constants.py | 3 --- strix/core/inputs.py | 3 +++ strix/core/runner.py | 2 +- strix/interface/__init__.py | 14 +------------- strix/interface/cli.py | 2 +- strix/interface/main.py | 37 +++++++++++++----------------------- strix/interface/tui/app.py | 2 +- tests/test_install_script.py | 12 +++++++----- 8 files changed, 27 insertions(+), 48 deletions(-) delete mode 100644 strix/core/constants.py diff --git a/strix/core/constants.py b/strix/core/constants.py deleted file mode 100644 index 9504d950f..000000000 --- a/strix/core/constants.py +++ /dev/null @@ -1,3 +0,0 @@ -"""Lightweight constants importable without pulling in the agent runtime.""" - -DEFAULT_MAX_TURNS = 500 diff --git a/strix/core/inputs.py b/strix/core/inputs.py index 4baf0ac96..aef1fe137 100644 --- a/strix/core/inputs.py +++ b/strix/core/inputs.py @@ -24,6 +24,9 @@ if TYPE_CHECKING: from strix.config.settings import ReasoningEffort +DEFAULT_MAX_TURNS = 500 + + def _accepts_required_tool_choice(model_name: str | None) -> bool: name = (model_name or "").strip().lower() for prefix in ("litellm/", "any-llm/"): diff --git a/strix/core/runner.py b/strix/core/runner.py index 18140d94f..fdb432d0c 100644 --- a/strix/core/runner.py +++ b/strix/core/runner.py @@ -24,7 +24,6 @@ from strix.config.models import ( uses_chat_completions_tool_schema, ) from strix.core.agents import AgentCoordinator -from strix.core.constants import DEFAULT_MAX_TURNS from strix.core.execution import ( respawn_subagents, run_agent_loop, @@ -34,6 +33,7 @@ from strix.core.execution import ( ) from strix.core.hooks import BudgetExceededError, ReportUsageHooks, recomputed_budget_flags from strix.core.inputs import ( + DEFAULT_MAX_TURNS, build_root_task, build_scope_context, make_model_settings, diff --git a/strix/interface/__init__.py b/strix/interface/__init__.py index 75abbf835..b0f97407c 100644 --- a/strix/interface/__init__.py +++ b/strix/interface/__init__.py @@ -1,16 +1,4 @@ -from typing import TYPE_CHECKING - - -if TYPE_CHECKING: - from .main import main +from .main import main __all__ = ["main"] - - -def __getattr__(name: str) -> object: - if name == "main": - from .main import main - - return main - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/strix/interface/cli.py b/strix/interface/cli.py index 1b6b00da8..c03e8c86c 100644 --- a/strix/interface/cli.py +++ b/strix/interface/cli.py @@ -13,7 +13,7 @@ from rich.panel import Panel from rich.text import Text from strix.config import load_settings -from strix.core.constants import DEFAULT_MAX_TURNS +from strix.core.inputs import DEFAULT_MAX_TURNS from strix.core.runner import run_strix_scan from strix.report.state import ReportState, set_global_report_state from strix.runtime import session_manager diff --git a/strix/interface/main.py b/strix/interface/main.py index 740304675..f42ed1d14 100644 --- a/strix/interface/main.py +++ b/strix/interface/main.py @@ -11,6 +11,9 @@ import sys from datetime import UTC, datetime from pathlib import Path +from agents.model_settings import ModelSettings +from agents.models.interface import ModelTracing +from docker.errors import DockerException from rich.console import Console from rich.panel import Panel from rich.text import Text @@ -21,7 +24,14 @@ from strix.config import ( load_settings, persist_current, ) -from strix.core.constants import DEFAULT_MAX_TURNS +from strix.config.models import ( + RECOMMENDED_MODEL_NAMES, + StrixProvider, + configure_sdk_model_defaults, + is_known_openai_bare_model, + is_recommended_or_frontier_model, +) +from strix.core.inputs import DEFAULT_MAX_TURNS from strix.core.paths import run_dir_for, runtime_state_dir from strix.interface.update_check import ( is_binary_install, @@ -49,6 +59,8 @@ from strix.interface.utils import ( rewrite_localhost_targets, validate_config_file, ) +from strix.report.state import get_global_report_state +from strix.report.writer import read_run_record, write_run_record from strix.telemetry import posthog, scarf from strix.telemetry.logging import configure_dependency_logging @@ -299,17 +311,6 @@ async def warm_up_llm(show_model_warning: bool = True) -> None: console = Console() logger.info("Warming up LLM connection") - from agents.model_settings import ModelSettings - from agents.models.interface import ModelTracing - - from strix.config.models import ( - RECOMMENDED_MODEL_NAMES, - StrixProvider, - configure_sdk_model_defaults, - is_known_openai_bare_model, - is_recommended_or_frontier_model, - ) - raw_model = "" try: settings = load_settings() @@ -773,8 +774,6 @@ Examples: def _persist_run_record(args: argparse.Namespace) -> None: - from strix.report.writer import write_run_record - run_dir = run_dir_for(args.run_name) run_dir.mkdir(parents=True, exist_ok=True) run_record = { @@ -798,8 +797,6 @@ def _persist_run_record(args: argparse.Namespace) -> None: def _load_resume_state(args: argparse.Namespace, parser: argparse.ArgumentParser) -> None: """Populate ``args.targets_info`` and friends from a prior run's run.json.""" - from strix.report.writer import read_run_record - run_dir = run_dir_for(args.resume) state_path = run_dir / "run.json" if not state_path.exists(): @@ -844,8 +841,6 @@ def _load_resume_state(args: argparse.Namespace, parser: argparse.ArgumentParser def display_completion_message(args: argparse.Namespace, results_path: Path) -> None: - from strix.report.state import get_global_report_state - console = Console() report_state = get_global_report_state() @@ -925,8 +920,6 @@ def display_completion_message(args: argparse.Namespace, results_path: Path) -> def pull_docker_image() -> None: - from docker.errors import DockerException - console = Console() client = check_docker_connection() @@ -1091,8 +1084,6 @@ def main() -> None: scarf.error("unhandled_exception") raise finally: - from strix.report.state import get_global_report_state - report_state = get_global_report_state() if report_state: status = {"interrupted": "interrupted", "error": "failed"}.get( @@ -1108,8 +1099,6 @@ def main() -> None: display_completion_message(args, results_path) if args.non_interactive: - from strix.report.state import get_global_report_state - report_state = get_global_report_state() if report_state and report_state.vulnerability_reports: sys.exit(2) diff --git a/strix/interface/tui/app.py b/strix/interface/tui/app.py index 3a14c5f07..cc5a36c4f 100644 --- a/strix/interface/tui/app.py +++ b/strix/interface/tui/app.py @@ -33,8 +33,8 @@ from textual.widgets.tree import TreeNode from strix.config import load_settings from strix.config.models import is_recommended_or_frontier_model -from strix.core.constants import DEFAULT_MAX_TURNS from strix.core.hooks import BudgetExceededError +from strix.core.inputs import DEFAULT_MAX_TURNS from strix.core.runner import run_strix_scan from strix.interface.tui.live_view import TuiLiveView from strix.interface.tui.messages import send_user_message_to_agent diff --git a/tests/test_install_script.py b/tests/test_install_script.py index 67ca48437..6da84619b 100644 --- a/tests/test_install_script.py +++ b/tests/test_install_script.py @@ -24,13 +24,15 @@ def _write_executable(path: Path, content: str) -> None: def _create_release_archive(tmp_path: Path) -> Path: - binary_name = f"strix-{RELEASE_VERSION}-{RELEASE_TARGET}" - binary_path = tmp_path / binary_name - _write_executable(binary_path, f"#!/bin/sh\nprintf 'strix {RELEASE_VERSION}\\n'\n") + bundle_name = f"strix-{RELEASE_VERSION}-{RELEASE_TARGET}" + bundle_dir = tmp_path / bundle_name + (bundle_dir / "_internal").mkdir(parents=True) + (bundle_dir / "_internal" / "base_library.zip").write_bytes(b"") + _write_executable(bundle_dir / "strix", f"#!/bin/sh\nprintf 'strix {RELEASE_VERSION}\\n'\n") - archive_path = tmp_path / f"{binary_name}.tar.gz" + archive_path = tmp_path / f"{bundle_name}.tar.gz" with tarfile.open(archive_path, "w:gz") as archive: - archive.add(binary_path, arcname=binary_name) + archive.add(bundle_dir, arcname=bundle_name) return archive_path