Skip to content

LoopLog: --omit-stderr flag to remove stderr from tree and preview #48

Description

@maddes8cht

Description

The LoopLog viewer writes stderr from every agent into the run log (always as a direct child of <agent>, core/engine.py:1144). That output is often the only way to diagnose a failure, but in normal operation it is noise the user does not want to read at all.

Today only --hide-system-tags exists, and it is purely a navigation toggle: system tags disappear from the treeview (except the first/last boundary sections per run root), but their content is still shown in the preview when a parent node is selected. This new feature behaves differently:

  • --omit-stderr removes stderr from both the treeview and the preview pane.
  • Even when a parent section (e.g. the agent) is selected, its stderr content is completely absent from the displayed text.

The verbs are intentionally different so the semantics stay distinguishable:

Flag Effect Semantics
--hide-system-tags treeview only "hide" = navigation (content still reachable via parent)
--omit-stderr treeview + preview "omit" = content is removed from the output

No boundary exception is needed for stderr: the engine always writes <stderr> nested inside <agent>, never at root level, so all stderr sections can be removed without losing header/summary information.

Scope

  • In: GUI checkbox, CLI --omit-stderr flag, preview stripping across all display paths, filter-dropdown handling.
  • Out: renaming the existing --hide-system-tags flag (name stays established), GUI toolbar button changes in ui/app.py (it still launches the viewer with --watch --wrap-lines only), any stderr boundary exception (not needed).

Preview paths that must become stderr-free

  1. Single-selection preview (_display_sections, len(secs) == 1)
  2. Multi-selection preview (parts loop)
  3. Filter view (matches loop)
  4. "Show entire file" mode (_on_show_all and the _rebuild_tree show-all path) — also stripped, confirmed with the user

Implementation plan

tools/looplog.py

  1. Parser (LogParser)

    • parse() caches self.sections and additionally collects self._stderr_ranges — the list of (start, end) line ranges of every stderr section.
    • get_raw_text(start, end, strip_markers=True, omit_stderr=False) gains an omit_stderr parameter; when True, lines falling inside any cached stderr range are skipped.
    • get_full_text(strip_markers=True, omit_stderr=False) passes the flag through.
  2. LoopLogApp

    • Constructor gains omit_stderr: bool = False; store self._start_omit_stderr.
    • _build_ui: add a checkbox "Omit stderr output" next to "Hide system tags" (reuse the BooleanVar + command pattern).
    • _insert_node: when omit is active and sec.tag == "stderr", skip the node (return ""). Use defensive getattr(self, "_omit_stderr", ...) so existing object.__new__-based tests keep working.
    • _display_sections, _on_show_all, and _rebuild_tree: pass omit_stderr=self._omit_stderr.get() to the text extraction calls.
    • _update_filter_options: when omit is active, remove "stderr" from the dropdown values and reset a set "stderr" filter to "all" — mirroring the existing system logic.
  3. CLI entry point (main)

    • Add --omit-stderr argparse flag (action="store_true").
    • Pass omit_stderr=args.omit_stderr to LoopLogApp(...).
    • Update the module usage docstring at the top of the file and the --help text.

tests/test_all.py (new tests)

  • Parser: get_raw_text(..., omit_stderr=True) removes stderr lines but keeps stdout.
  • _insert_node skips stderr nodes when omit is active; includes them when not.
  • _update_filter_options removes stderr from the dropdown and resets a stderr filter when omit is active.
  • _display_sections strips stderr from the preview text (single selection and multi-selection).
  • "Show entire file" path also strips stderr when omit is active.

Explicitly NOT changed

  • --hide-system-tags (name and behavior remain)
  • ui/app.py toolbar button (still launches viewer with --watch --wrap-lines)
  • Any stderr boundary exception (stderr is never root-level)

Verification

  • python -m pytest tests\test_all.py -q — existing 251 tests plus the new ones must pass.
  • python -m py_compile tools\looplog.py tests\test_all.py
  • Manual smoke: run the viewer on a real log with both checkboxes and confirm stderr appears in the tree+preview with neither active, disappears from both with "Omit stderr output" active, and that "Show entire file" also becomes stderr-free.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions