Skip to content

Duplicate aiui launcher logic in cli/commands/ui.py default callback #2253

Description

@MervinPraison

Summary

cli/commands/ui.py defines a reusable _launch_aiui_app() helper, but the default ui() callback re-implements the same install-check, app-file resolution and subprocess-launch logic inline instead of calling it. The two copies are textually near-identical, so a fix to one (e.g. the install hint or the aiuipython -m praisonaiui.cli fallback) silently misses the other.

Current behaviour

Code citations from src/praisonai/praisonai/cli/commands/ui.py:

  • cli/commands/ui.py:45-108_launch_aiui_app(...): checks importlib.util.find_spec("praisonaiui"), resolves the app file, runs ["aiui", "run", ...], and falls back to [sys.executable, "-m", "praisonaiui.cli", ...].
  • cli/commands/ui.py:~138-181 — the default ui() callback (when ctx.invoked_subcommand is None) repeats the identical install check, app-file resolution and the same subprocess launch + fallback block.

Why it matters

Maintenance / duplication. The default praisonai ui path and the helper used by the sub-commands (ui agents, ui bot, ui realtime) can drift apart; a bug fixed in one launch path remains in the other.

Category

Duplicate

Capability preserved

praisonai ui and all ui sub-commands continue to work exactly as today, including the praisonaiui install check, custom --app handling, default-app bootstrap, --port/--host/--reload, and the aiuipython -m praisonaiui.cli fallback.

Proposed approach

Merge. Replace the inline block in the ui() callback with a single call to the existing _launch_aiui_app(...), passing the chat defaults. Behaviour is identical; the callback already holds every argument the helper needs.

Resolution sketch

# Before — inline duplicate inside ui() callback
if ctx.invoked_subcommand is not None:
    return
# ...install check... resolve app file... subprocess.run(["aiui","run",...]) + fallback...

# After — delegate to the existing helper
if ctx.invoked_subcommand is not None:
    return
_launch_aiui_app("ui_chat", "ui_chat", port, host, app_file, reload, "Chat")

(If the callback's bespoke _ensure_default_app() resolution must be retained, fold that one difference into _launch_aiui_app behind a parameter so a single function owns the launch path.)

Layer placement

  • Primary layer: wrapper
  • Touches core/tools/plugins (optional): none
  • 3-way surface (CLI + YAML + Python): CLI only (UI launch command); preserved yes

Severity

Low — small, contained duplication; no runtime cost, purely maintenance.

Validation

Traced: both blocks read in full; install check, command vector and fallback are identical bar minor formatting and the _ensure_default_app() vs bundled-copy detail. Not intentional robustness. No user-facing change.

Keep unchanged

Keep the praisonaiui install check and its pip install "praisonai[ui]" hint, the aiui→module fallback, the per-UI sub-commands (agents, bot, chat, realtime, dashboard), and the bundled default_app.py bootstrap behaviour.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingclaudeAuto-trigger Claude analysis

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions