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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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