Skip to content

Comments

Refactor (gradio part 6) mode wiring decomposition#663

Merged
ChuxiJ merged 5 commits intoace-step:mainfrom
1larity:sync/pr4-results-aux-wiring-20260220
Feb 21, 2026
Merged

Refactor (gradio part 6) mode wiring decomposition#663
ChuxiJ merged 5 commits intoace-step:mainfrom
1larity:sync/pr4-results-aux-wiring-20260220

Conversation

@1larity
Copy link
Contributor

@1larity 1larity commented Feb 21, 2026

Summary

Continue decomposition of acestep/ui/gradio/events/__init__.py into focused wiring modules while preserving behaviour and IO ordering.

Changes

  • Extract training wiring from facade into:
    • training_run_wiring.py
    • training_dataset_builder_wiring.py
    • training_dataset_preprocess_wiring.py
  • Extract results display/restore/LRC wiring into:
    • results_display_wiring.py
  • Extract metadata file-load wiring into:
    • generation_metadata_file_wiring.py
  • Reduce acestep/ui/gradio/events/__init__.py to thin orchestration (121 LOC).
  • Add/extend contract and unit tests:
    • decomposition_contract_test.py
    • generation_metadata_file_wiring_test.py
    • results_display_wiring_test.py
    • docstring_coverage_test.py
    • existing context_test.py remains green.

Behaviour/Interface Impact

  • No intended behaviour changes.
  • No public interface changes.
  • Event input/output ordering preserved.

Validation

  • python acestep/ui/gradio/events/wiring/decomposition_contract_test.py
  • python acestep/ui/gradio/events/wiring/context_test.py
  • python acestep/ui/gradio/events/wiring/generation_metadata_file_wiring_test.py
  • python acestep/ui/gradio/events/wiring/results_display_wiring_test.py
  • python acestep/ui/gradio/events/wiring/docstring_coverage_test.py
  • python -m py_compile ... on changed modules

Code reviews by GLM 5 raised no issues.

Risk

  • Low: source-level refactor with contract tests guarding delegation and ordering.

Summary by CodeRabbit

  • Refactor

    • Reorganized event handling infrastructure to improve code modularity and maintainability across generation, results display, and training features.
  • Tests

    • Added comprehensive unit tests for event wiring modules to ensure stability and contract compliance.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 21, 2026

📝 Walkthrough

Walkthrough

This PR refactors Gradio event handler registration by decomposing monolithic wiring logic from the main events module into specialized, modularized wiring modules. Large blocks of direct event callback definitions are replaced with calls to new register_*_handler functions, improving code organization and maintainability.

Changes

Cohort / File(s) Summary
Event Handler Registration Refactoring
acestep/ui/gradio/events/__init__.py, acestep/ui/gradio/events/wiring/__init__.py
Consolidated direct event wiring into calls to new register_*_handler functions (generation metadata, results display, training dataset, training run). Public API exports expanded to include seven new wiring helpers.
Generation Wiring Modules
acestep/ui/gradio/events/wiring/generation_metadata_file_wiring.py, acestep/ui/gradio/events/wiring/results_display_wiring.py
New modules implementing metadata file loading with auto-checkbox synchronization and results display (save/download, parameter restore, LRC subtitle sync). Includes JavaScript snippet for download orchestration.
Training Wiring Modules
acestep/ui/gradio/events/wiring/training_run_wiring.py, acestep/ui/gradio/events/wiring/training_dataset_builder_wiring.py, acestep/ui/gradio/events/wiring/training_dataset_preprocess_wiring.py, acestep/ui/gradio/events/wiring/training_lokr_wiring.py
New modules for training workflows including dataset building, preprocessing, standard training, and LoKr training. Implement state normalization, progress streaming, and handler registration for UI components.
Testing Infrastructure
acestep/ui/gradio/events/wiring/decomposition_contract_generation_test.py, acestep/ui/gradio/events/wiring/decomposition_contract_training_test.py, acestep/ui/gradio/events/wiring/docstring_coverage_test.py
New AST-based test modules validating wiring contracts, handler references, and docstring coverage across generation and training wiring layers. Contract tests verify delegation to correct handlers and parameter routing.
Test Wiring Modules
acestep/ui/gradio/events/wiring/generation_metadata_file_wiring_test.py, acestep/ui/gradio/events/wiring/results_display_wiring_test.py
New test modules validating output ordering, handler references, JavaScript content, and slot coverage in generation metadata and results display wiring.
Test Utilities
acestep/ui/gradio/events/wiring/ast_test_utils.py, acestep/ui/gradio/events/wiring/decomposition_contract_helpers.py
New utility modules providing AST parsing helpers (load_module_ast, subscript_key) and loader functions for accessing specific AST nodes from wiring modules used by contract tests.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~65 minutes

Possibly related PRs

Suggested reviewers

  • ChuxiJ

Poem

🐰 Events were scattered, callbacks run deep,
Till wiring modules whispered "let's reap!"
From monoliths vast to handlers so neat,
Registration by function—refactor complete!
Tests verify contracts, and docstrings align,
The UI now blooms, decomposed so fine! 🌱

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main refactoring effort: decomposing Gradio event wiring mode handlers into focused modules to improve maintainability.
Docstring Coverage ✅ Passed Docstring coverage is 98.61% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (6)
acestep/ui/gradio/events/wiring/training_run_wiring.py (4)

45-47: Use f-string conversion flag instead of str(exc).

Static analysis (RUF010) suggests using the !s conversion flag for cleaner f-string formatting.

♻️ Proposed fix
-        except Exception as exc:  # pragma: no cover - defensive UI wrapper
-            logger.exception("Training wrapper error")
-            yield f"❌ Error: {str(exc)}", str(exc), None, state
+        except Exception as exc:  # pragma: no cover - defensive UI wrapper
+            logger.exception("Training wrapper error")
+            yield f"❌ Error: {exc!s}", f"{exc!s}", None, state
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@acestep/ui/gradio/events/wiring/training_run_wiring.py` around lines 45 - 47,
Replace explicit str(exc) conversions with f-string conversion flags to follow
RUF010: in the except block inside training_run_wiring (the exception handler
that logs "Training wrapper error" and yields the error tuple), use the !s
conversion on the exception in the f-string and the second yielded value (e.g.,
yield f"❌ Error: {exc!s}", exc!s, None, state) so the exception is converted via
the f-string conversion flag instead of calling str().

21-36: Use descriptive parameter names for wrapper function signatures.

The abbreviated names (r, a, d, lr, ep, bs, ga, se, sh, sd, od, rc, ts) are cryptic and hinder readability. Since this is a public wrapper that streams UI progress, meaningful names would improve maintainability.

♻️ Suggested parameter naming
 def training_wrapper(
     tensor_dir: Any,
-    r: Any,
-    a: Any,
-    d: Any,
-    lr: Any,
-    ep: Any,
-    bs: Any,
-    ga: Any,
-    se: Any,
-    sh: Any,
-    sd: Any,
-    od: Any,
-    rc: Any,
-    ts: Any,
+    lora_rank: Any,
+    lora_alpha: Any,
+    lora_dropout: Any,
+    learning_rate: Any,
+    epochs: Any,
+    batch_size: Any,
+    gradient_accumulation: Any,
+    save_every: Any,
+    shift: Any,
+    seed: Any,
+    output_dir: Any,
+    resume_checkpoint: Any,
+    training_state: Any,
 ) -> Iterator[tuple[Any, Any, Any, dict[str, bool]]]:

As per coding guidelines: "Use clear names that describe behavior, not implementation trivia in Python code."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@acestep/ui/gradio/events/wiring/training_run_wiring.py` around lines 21 - 36,
The training_wrapper function signature uses cryptic short parameter names
(tensor_dir, r, a, d, lr, ep, bs, ga, se, sh, sd, od, rc, ts) which reduces
readability; rename these parameters to descriptive names (e.g., replace
r->run_id or record, a->artifact_path or assets, d->dataset, lr->learning_rate,
ep->epochs, bs->batch_size, ga->grad_accumulation, se->seed, sh->shuffle,
sd->save_dir, od->output_dir, rc->resume_checkpoint, ts->timestamp) and update
all internal references and any callers to use the new names to preserve
behavior in training_wrapper (and its return type Iterator[tuple[Any, Any, Any,
dict[str, bool]]]).

1-226: Module exceeds the 200 LOC hard cap.

At ~226 lines, this module exceeds the established guideline. Consider extracting the LoKr wiring (lines 164-226) into a separate training_lokr_wiring.py module to improve maintainability.

Based on learnings: "only raise module-size concerns when a file exceeds 200 lines of code (LOC)."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@acestep/ui/gradio/events/wiring/training_run_wiring.py` around lines 1 - 226,
This module is over the 200-line cap; extract the LoKr-specific wiring into a
new training_lokr_wiring.py to keep register_training_run_handlers small: move
_build_lokr_training_wrapper and all LoKr-related click registrations
(references: _build_lokr_training_wrapper, lokr_training_wrapper,
start_lokr_training_btn, stop_lokr_training_btn, refresh_lokr_export_epochs_btn,
export_lokr_btn, and the training_section keys prefixed with "lokr_") into that
new module, export a function (e.g., register_lokr_training_handlers(context))
that registers only those handlers, and replace the LoKr block in
register_training_run_handlers with a single call to the new
register_lokr_training_handlers while importing it at top; ensure
_normalize_training_state and non-LoKr wiring remain in the original file and
update any imports/exports accordingly.

99-101: Use f-string conversion flag here as well.

Same RUF010 issue as the standard training wrapper.

♻️ Proposed fix
-        except Exception as exc:  # pragma: no cover - defensive UI wrapper
-            logger.exception("LoKr training wrapper error")
-            yield f"❌ Error: {str(exc)}", str(exc), None, state
+        except Exception as exc:  # pragma: no cover - defensive UI wrapper
+            logger.exception("LoKr training wrapper error")
+            yield f"❌ Error: {exc!s}", f"{exc!s}", None, state
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@acestep/ui/gradio/events/wiring/training_run_wiring.py` around lines 99 -
101, Replace the plain str(exc) usage with the f-string conversion flag !r so
exception objects are represented with their repr; specifically update the yield
line that currently yields f"❌ Error: {str(exc)}", str(exc), None, state to use
f"❌ Error: {exc!r}", exc!r, None, state and ensure the logger.exception("LoKr
training wrapper error") line remains (it already logs the traceback) so the
human-readable and machine-friendly exception representation comes from using
{exc!r} in the yield.
acestep/ui/gradio/events/wiring/decomposition_contract_test.py (1)

1-314: Consider splitting test file if it grows further.

At ~314 LOC, this test file is approaching complexity limits. If more wiring modules are added, consider splitting into decomposition_contract_generation_test.py and decomposition_contract_training_test.py to maintain focused test scope.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@acestep/ui/gradio/events/wiring/decomposition_contract_test.py` around lines
1 - 314, Split the large DecompositionContractTests into two focused test files:
create decomposition_contract_generation_test.py containing the
generation-related tests (keep methods
test_setup_event_handlers_uses_generation_wiring_helpers,
test_generation_metadata_file_wiring_calls_expected_handlers,
test_generation_mode_wiring_uses_mode_ui_outputs_variable,
test_generation_run_wiring_calls_expected_results_handlers,
test_batch_navigation_wiring_calls_expected_results_handlers,
test_results_display_wiring_calls_expected_results_handlers) and create
decomposition_contract_training_test.py containing the training-related tests
(keep methods
test_setup_training_event_handlers_uses_training_run_wiring_helper,
test_training_run_wiring_calls_expected_training_handlers,
test_training_dataset_builder_wiring_calls_expected_handlers,
test_training_dataset_preprocess_wiring_calls_expected_handlers); extract the
top-level helpers and path constants (functions like
_load_setup_event_handlers_node, _load_setup_training_event_handlers_node,
_load_generation_mode_wiring_node, _load_generation_run_wiring_node,
_load_generation_batch_navigation_wiring_node,
_load_generation_metadata_file_wiring_module, _load_training_run_wiring_module,
_load_training_dataset_preprocess_wiring_module,
_load_training_dataset_builder_wiring_module,
_load_results_display_wiring_module and constants like _EVENTS_INIT_PATH etc.)
into a small shared module (e.g., decomposition_contract_helpers.py) and import
those helpers from both new test files so each test file is concise and focused.
acestep/ui/gradio/events/wiring/results_display_wiring_test.py (1)

50-61: Consider extracting shared AST helpers if pattern grows.

The _load_module_ast helper mirrors the one in generation_metadata_file_wiring_test.py. For two occurrences, inline duplication is acceptable; if more test files adopt this pattern, consider a shared test_utils module.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@acestep/ui/gradio/events/wiring/results_display_wiring_test.py` around lines
50 - 61, The helper _load_module_ast (and related helpers like _subscript_key)
is duplicated in another test file; extract these shared AST utilities into a
common test utility module (e.g., test_utils or tests/_ast_helpers) and import
them from there in results_display_wiring_test.py and
generation_metadata_file_wiring_test.py; move the functions _load_module_ast and
_subscript_key into the new module, keep the behavior (reading with
encoding="utf-8" and returning ast.Module), update the tests to import the
helpers, and run tests to ensure no import/name conflicts.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@acestep/ui/gradio/events/wiring/docstring_coverage_test.py`:
- Line 47: The current assignment module_name =
str(module_path.relative_to(Path.cwd())) can raise ValueError when tests run
outside the repo root; update the logic around the module_name calculation (the
module_path -> module_name conversion) to be defensive: attempt
module_path.relative_to(Path.cwd()) in a try block and on ValueError fall back
to a stable identifier such as module_path.name (or module_path.as_posix()),
ensuring module_path and module_name are used accordingly so callers still
receive a readable module identifier.

In `@acestep/ui/gradio/events/wiring/results_display_wiring.py`:
- Line 71: Update the stale inline comment next to the setTimeout call that
currently reads "// 300ms interval to avoid browser blocking" — change it to
reflect the actual delay used (index * 1000), e.g., "// 1000ms interval per
index to avoid browser blocking" or remove the misleading duration; locate the
setTimeout invocation referencing "index * 1000" in results_display_wiring.py
and update its comment accordingly.

In `@acestep/ui/gradio/events/wiring/training_dataset_builder_wiring.py`:
- Line 94: The f-string in the lambda (fn=lambda status: f"{status or '\u2705
Auto-label complete.'}\n\u2705 Preview refreshed.") uses a \u escape inside an
f-string which is invalid on Python 3.11; replace the escape by extracting the
checkmark emoji to a constant (e.g., CHECKMARK = "✅") or use the emoji literal,
then rebuild the string using that symbol (e.g., use the CHECKMARK variable in
the lambda expression for both the "Auto-label complete." and "Preview
refreshed." parts) so the f-string contains no \u escape sequences.

---

Nitpick comments:
In `@acestep/ui/gradio/events/wiring/decomposition_contract_test.py`:
- Around line 1-314: Split the large DecompositionContractTests into two focused
test files: create decomposition_contract_generation_test.py containing the
generation-related tests (keep methods
test_setup_event_handlers_uses_generation_wiring_helpers,
test_generation_metadata_file_wiring_calls_expected_handlers,
test_generation_mode_wiring_uses_mode_ui_outputs_variable,
test_generation_run_wiring_calls_expected_results_handlers,
test_batch_navigation_wiring_calls_expected_results_handlers,
test_results_display_wiring_calls_expected_results_handlers) and create
decomposition_contract_training_test.py containing the training-related tests
(keep methods
test_setup_training_event_handlers_uses_training_run_wiring_helper,
test_training_run_wiring_calls_expected_training_handlers,
test_training_dataset_builder_wiring_calls_expected_handlers,
test_training_dataset_preprocess_wiring_calls_expected_handlers); extract the
top-level helpers and path constants (functions like
_load_setup_event_handlers_node, _load_setup_training_event_handlers_node,
_load_generation_mode_wiring_node, _load_generation_run_wiring_node,
_load_generation_batch_navigation_wiring_node,
_load_generation_metadata_file_wiring_module, _load_training_run_wiring_module,
_load_training_dataset_preprocess_wiring_module,
_load_training_dataset_builder_wiring_module,
_load_results_display_wiring_module and constants like _EVENTS_INIT_PATH etc.)
into a small shared module (e.g., decomposition_contract_helpers.py) and import
those helpers from both new test files so each test file is concise and focused.

In `@acestep/ui/gradio/events/wiring/results_display_wiring_test.py`:
- Around line 50-61: The helper _load_module_ast (and related helpers like
_subscript_key) is duplicated in another test file; extract these shared AST
utilities into a common test utility module (e.g., test_utils or
tests/_ast_helpers) and import them from there in results_display_wiring_test.py
and generation_metadata_file_wiring_test.py; move the functions _load_module_ast
and _subscript_key into the new module, keep the behavior (reading with
encoding="utf-8" and returning ast.Module), update the tests to import the
helpers, and run tests to ensure no import/name conflicts.

In `@acestep/ui/gradio/events/wiring/training_run_wiring.py`:
- Around line 45-47: Replace explicit str(exc) conversions with f-string
conversion flags to follow RUF010: in the except block inside
training_run_wiring (the exception handler that logs "Training wrapper error"
and yields the error tuple), use the !s conversion on the exception in the
f-string and the second yielded value (e.g., yield f"❌ Error: {exc!s}", exc!s,
None, state) so the exception is converted via the f-string conversion flag
instead of calling str().
- Around line 21-36: The training_wrapper function signature uses cryptic short
parameter names (tensor_dir, r, a, d, lr, ep, bs, ga, se, sh, sd, od, rc, ts)
which reduces readability; rename these parameters to descriptive names (e.g.,
replace r->run_id or record, a->artifact_path or assets, d->dataset,
lr->learning_rate, ep->epochs, bs->batch_size, ga->grad_accumulation, se->seed,
sh->shuffle, sd->save_dir, od->output_dir, rc->resume_checkpoint, ts->timestamp)
and update all internal references and any callers to use the new names to
preserve behavior in training_wrapper (and its return type Iterator[tuple[Any,
Any, Any, dict[str, bool]]]).
- Around line 1-226: This module is over the 200-line cap; extract the
LoKr-specific wiring into a new training_lokr_wiring.py to keep
register_training_run_handlers small: move _build_lokr_training_wrapper and all
LoKr-related click registrations (references: _build_lokr_training_wrapper,
lokr_training_wrapper, start_lokr_training_btn, stop_lokr_training_btn,
refresh_lokr_export_epochs_btn, export_lokr_btn, and the training_section keys
prefixed with "lokr_") into that new module, export a function (e.g.,
register_lokr_training_handlers(context)) that registers only those handlers,
and replace the LoKr block in register_training_run_handlers with a single call
to the new register_lokr_training_handlers while importing it at top; ensure
_normalize_training_state and non-LoKr wiring remain in the original file and
update any imports/exports accordingly.
- Around line 99-101: Replace the plain str(exc) usage with the f-string
conversion flag !r so exception objects are represented with their repr;
specifically update the yield line that currently yields f"❌ Error: {str(exc)}",
str(exc), None, state to use f"❌ Error: {exc!r}", exc!r, None, state and ensure
the logger.exception("LoKr training wrapper error") line remains (it already
logs the traceback) so the human-readable and machine-friendly exception
representation comes from using {exc!r} in the yield.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
acestep/ui/gradio/events/wiring/training_lokr_wiring.py (1)

61-63: Minor inconsistency in exception formatting.

This wrapper uses {exc!r} (repr) while training_run_wiring.py line 63 uses {exc!s} (str). Consider aligning both to use the same format for consistency. The !s format typically produces cleaner user-facing messages.

♻️ Optional consistency fix
-            yield f"\u274c Error: {exc!r}", f"{exc!r}", None, state
+            yield f"\u274c Error: {exc!s}", f"{exc!s}", None, state
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@acestep/ui/gradio/events/wiring/training_lokr_wiring.py` around lines 61 -
63, The exception message in the LoKr training wrapper (inside the except block
that logs via logger.exception and yields the error) uses repr ({exc!r}) for the
user-facing yield; change the yield formatting to use str ({exc!s}) to match
training_run_wiring.py and produce cleaner user-facing messages—update the yield
line that currently yields f"\u274c Error: {exc!r}", f"{exc!r}", None, state to
use {exc!s} instead while leaving logger.exception(...) as-is.
acestep/ui/gradio/events/wiring/decomposition_contract_helpers.py (1)

29-89: Consider consolidating repetitive loader functions.

The loader functions for FunctionDef nodes (lines 29-89) follow an identical pattern: read file → parse → search for function name → return or raise. This could be consolidated into a generic helper.

♻️ Optional refactor to reduce duplication
def _load_function_def(path: Path, function_name: str) -> ast.FunctionDef:
    """Load a specific FunctionDef from the given module path."""
    source = path.read_text(encoding="utf-8")
    module = ast.parse(source)
    for node in module.body:
        if isinstance(node, ast.FunctionDef) and node.name == function_name:
            return node
    raise AssertionError(f"{function_name} not found")


def load_setup_event_handlers_node() -> ast.FunctionDef:
    """Return the AST node for ``setup_event_handlers``."""
    return _load_function_def(_EVENTS_INIT_PATH, "setup_event_handlers")

This would reduce the 5 similar loader functions to concise one-liners.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@acestep/ui/gradio/events/wiring/decomposition_contract_helpers.py` around
lines 29 - 89, Several loader functions (load_setup_event_handlers_node,
load_setup_training_event_handlers_node, load_generation_mode_wiring_node,
load_generation_run_wiring_node, load_generation_batch_navigation_wiring_node)
duplicate the same read/parse/search pattern; add a single helper
_load_function_def(path: Path, function_name: str) that reads the file,
ast.parse()s it, finds and returns the ast.FunctionDef or raises
AssertionError(f"{function_name} not found"), then replace each of the above
function bodies with a one-line return calling _load_function_def with the
appropriate _EVENTS_INIT_PATH / _MODE_WIRING_PATH / _RUN_WIRING_PATH /
_BATCH_NAV_WIRING_PATH and the target function name; keep
load_generation_metadata_file_wiring_module as-is since it returns ast.Module.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@acestep/ui/gradio/events/wiring/decomposition_contract_helpers.py`:
- Around line 29-89: Several loader functions (load_setup_event_handlers_node,
load_setup_training_event_handlers_node, load_generation_mode_wiring_node,
load_generation_run_wiring_node, load_generation_batch_navigation_wiring_node)
duplicate the same read/parse/search pattern; add a single helper
_load_function_def(path: Path, function_name: str) that reads the file,
ast.parse()s it, finds and returns the ast.FunctionDef or raises
AssertionError(f"{function_name} not found"), then replace each of the above
function bodies with a one-line return calling _load_function_def with the
appropriate _EVENTS_INIT_PATH / _MODE_WIRING_PATH / _RUN_WIRING_PATH /
_BATCH_NAV_WIRING_PATH and the target function name; keep
load_generation_metadata_file_wiring_module as-is since it returns ast.Module.

In `@acestep/ui/gradio/events/wiring/training_lokr_wiring.py`:
- Around line 61-63: The exception message in the LoKr training wrapper (inside
the except block that logs via logger.exception and yields the error) uses repr
({exc!r}) for the user-facing yield; change the yield formatting to use str
({exc!s}) to match training_run_wiring.py and produce cleaner user-facing
messages—update the yield line that currently yields f"\u274c Error: {exc!r}",
f"{exc!r}", None, state to use {exc!s} instead while leaving
logger.exception(...) as-is.

@ChuxiJ ChuxiJ merged commit 59b874a into ace-step:main Feb 21, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants