From 74944832791b780d00481b03878becef0542414f Mon Sep 17 00:00:00 2001 From: ThomasCross Date: Fri, 24 Apr 2026 14:51:42 +0100 Subject: [PATCH 1/4] refactor: move module collect commands to utilities --- spikee/list.py | 295 ++++++++++++------------------------ spikee/utilities/llm.py | 5 +- spikee/utilities/modules.py | 70 ++++++++- 3 files changed, 173 insertions(+), 197 deletions(-) diff --git a/spikee/list.py b/spikee/list.py index 3b4c7bc..5942edf 100644 --- a/spikee/list.py +++ b/spikee/list.py @@ -4,7 +4,7 @@ import importlib.util import pkgutil from dataclasses import dataclass -from typing import List +from typing import List, Optional from rich.console import Console from rich.table import Table @@ -12,38 +12,22 @@ from rich.rule import Rule import rich.box +from spikee.templates import module from spikee.utilities.enums import ModuleTag, module_tag_to_colour, formatting_priority from spikee.utilities.modules import ( + load_module_from_path, get_options_from_module, get_description_from_module, + collect_seeds, + collect_datasets, + collect_modules, ) console = Console() def list_seeds(args): - base = Path(os.getcwd(), "datasets") - if not base.is_dir(): - console.print( - Panel("No 'datasets/' folder found", title="[seeds]", style="red") - ) - return - - want = { - "base_user_inputs.jsonl", - "base_documents.jsonl", - "standalone_user_inputs.jsonl", - "standalone_attacks.jsonl", - } - - seeds = sorted( - { - d.name - for d in base.iterdir() - if d.is_dir() and any((d / fn).is_file() for fn in want) - } - ) - + seeds = collect_seeds() console.print( Panel( "\n".join(seeds) if seeds else "(none)", title="[seeds] Local", style="cyan" @@ -52,17 +36,12 @@ def list_seeds(args): def list_datasets(args): - base = Path(os.getcwd(), "datasets") - if not base.is_dir(): - console.print( - Panel("No 'datasets/' folder found", title="[datasets]", style="red") + files = collect_datasets() + console.print( + Panel( + "\n".join(files) if files else "(none)", title="[datasets] Local", style="cyan" ) - return - files = [f.name for f in base.glob("*.jsonl")] - panel = Panel( - "\n".join(files) if files else "(none)", title="[datasets] Local", style="cyan" ) - console.print(panel) # --- Helpers --- @@ -71,136 +50,76 @@ def list_datasets(args): @dataclass class Module: name: str - options: list - util_llm: bool = False - tags: List[ModuleTag] = None - description: str = "" - - -def _load_module(name, path: Path): - spec = importlib.util.spec_from_file_location(name, path) - mod = importlib.util.module_from_spec(spec) - spec.loader.exec_module(mod) - return mod - - -def _collect_local(module_type: str): - entries = [] - any_util_llm = False - - path = Path(os.getcwd()) / module_type - if path.is_dir(): - for p in sorted(path.glob("*.py")): - if p.name == "__init__.py": - continue - name = p.stem - opts = None - try: - mod = _load_module(f"{module_type}.{name}", p) - opts = get_options_from_module(mod, module_type) - description = get_description_from_module(mod, module_type) - - if opts is not None and isinstance(opts, tuple) and len(opts) == 2: - util_llm = opts[1] - opts = opts[0] - else: - util_llm = False + options: Optional[List[str]] = None + tags: Optional[List[ModuleTag]] = None + description: Optional[str] = "" - # Get classification - if description is not None and len(description) == 2: - tags, description = description - else: - tags, description = [], "" - - except (ModuleNotFoundError, ImportError): - opts = [""] - util_llm = False - tags = [] - description = "" - - except Exception as e: - error = e if len(str(e)) < 70 else str(e)[:70] + "..." - - opts = [f""] - util_llm = False - tags = [] - description = "" - - entries.append(Module(name, opts, util_llm, tags, description)) - if util_llm: - any_util_llm = True - - return entries, any_util_llm - - -def _collect_builtin(pkg: str, module_type: str): - entries = [] - any_util_llm = False - - try: - pkg_mod = importlib.import_module(pkg) - for _, name, is_pkg in pkgutil.iter_modules(pkg_mod.__path__): - if name == "__init__" or is_pkg: - continue - opts = None - try: - mod = importlib.import_module(f"{pkg}.{name}") - opts = get_options_from_module(mod, module_type) - description = get_description_from_module(mod, module_type) - - if opts is not None and isinstance(opts, tuple) and len(opts) == 2: - util_llm = opts[1] - opts = opts[0] - else: - util_llm = False +def _render_section( + module_type: str, + local, + builtin, + add_description: bool = False, + tag_line: str = "Available options", +): + console.print(Rule(f"[bold]{module_type.capitalize()}[/bold]")) - # Get classification - if description is not None and len(description) == 2: - tags, description = description - else: - tags, description = [], "" + uses_llm = False + local_entries = [] + builtin_entries = [] - except (ModuleNotFoundError, ImportError): - opts = [""] - util_llm = False - tags = [] - description = "" + def collect_module_data(module): + uses_llm = False - except Exception as e: - error = e if len(str(e)) < 70 else str(e)[:70] + "..." + try: + mod = load_module_from_path(module, module_type) - opts = [f""] - util_llm = False - tags = [] - description = "" + options_data = get_options_from_module(mod) + if options_data is not None and isinstance(options_data, tuple) and len(options_data) == 2: + if options_data[1]: + uses_llm = True - # traceback.print_exc() + options = options_data[0] - entries.append(Module(name, opts, util_llm, tags, description)) - if util_llm: - any_util_llm = True - except ModuleNotFoundError: - pass - return entries, any_util_llm + description_data = get_description_from_module(mod) + if description_data is not None and len(description_data) == 2: + tags, description = description_data + else: + tags, description = [], "" + + except Exception as e: + error = e if len(str(e)) < 70 else str(e)[:70] + "..." + options = [f""] + tags = [] + description = "" + + module_data = Module( + name=module, + options=options, + tags=tags, + description=description, + ) + return module_data, uses_llm + for local_module in local: + module, mod_uses_llm = collect_module_data(local_module) + local_entries.append(module) + if mod_uses_llm: + uses_llm = True -def _render_section( - title: str, - local_entries, - builtin_entries, - util_llm: bool = False, - description: bool = False, - tag_line: str = "Available options", -): - console.print(Rule(f"[bold]{title}[/bold]")) + for builtin_module in builtin: + module, mod_uses_llm = collect_module_data(builtin_module) + builtin_entries.append(module) + if mod_uses_llm: + uses_llm = True # If any module in this section uses the built-in LLM service, show a note about LLM options - if util_llm: + if uses_llm: + providers, _, _ = collect_modules("providers") console.print( Panel( f"""[yellow]Note:[/yellow] Modules with a [yellow][LLM][/yellow] tag, use the built-in LLM service. The LLM options are available, using 'model=