Skip to content

Release v0.30.0#938

Merged
lchoquel merged 4 commits into
mainfrom
release/v0.30.0
May 25, 2026
Merged

Release v0.30.0#938
lchoquel merged 4 commits into
mainfrom
release/v0.30.0

Conversation

@lchoquel
Copy link
Copy Markdown
Member

@lchoquel lchoquel commented May 25, 2026

Release v0.30.0

Bumps version from 0.29.1 to 0.30.0.

Changelog

Fixed

  • console_log_target package default is now stderr (was stdout). Logs now stay off the data channel by default, matching the intent of PR feature/JSONContent #452 ("default to stderr for outputs happening before initialization"). Downstream tooling that parses pipelex / pipelex-agent stdout as JSON (e.g. mthds-js's PipelexRunner) is no longer at risk of stdout pollution from package-level logs — the bug was latent for stock installs because the agent-CLI JSON paths happen not to log at INFO+, but surfaced for anyone who raised package_log_levels.pipelex to DEBUG or added a setup-time log on the command path. The same flip is applied to the kit template (pipelex/kit/configs/pipelex.toml) that pipelex init copies to ~/.pipelex/. Note: console_print_target is intentionally left at stdout — the main pipelex CLI emits human-facing tables (show backends, show models, which, doctor) via that channel, and downstream piping (pipelex show backends > out.txt) must keep working.

  • pipelex-agent now pins both console targets to stderr regardless of user config. make_pipelex_for_agent_cli injects config_overrides into Pipelex.make() that force console_log_target = "stderr" and console_print_target = "stderr" from the very first log/print fired during init, so a user override of either knob in ~/.pipelex/pipelex.toml can no longer leak diagnostics onto the agent CLI's JSON data channel. Defense-in-depth post-init calls to log.redirect_to_stderr() and get_pipelex_hub().set_console_print_target(STDERR) remain. A new adversarial E2E test (tests/e2e/agent_cli/test_stdout_is_clean_json.py::test_models_json_stdout_resists_user_targets_override_to_stdout) pins the contract by overriding both targets to stdout and package_log_levels.pipelex to DEBUG and asserting json.loads(stdout) still parses.


Summary by cubic

Release v0.30.0 hardens pipelex-agent so stdout stays clean JSON and flips package log defaults to stderr. The human pipelex CLI keeps tables on stdout for redirects.

  • Bug Fixes
    • Defaults: console_log_target now stderr in package and kit; console_print_target stays stdout.
    • Agent CLI: forces both console targets to stderr from the first init step and applies output discipline so JSON on stdout remains parseable even under user overrides.
    • Doctor:
      • Runs filesystem checks before bootstrap; respects --global by scoping model/backend paths to the provided config dir.
      • Preserves partial results on config errors; adds checks.models.skipped and renders a warning icon.
      • Human doctor now catches PipelexConfigError from bootstrap and shows the translated message under “Models” instead of a generic error.
      • Agent doctor invokes output discipline before check_models to prevent early log leakage to stdout.
    • Config/logging robustness:
      • ConfigLoader.load_config and PipelexHub.setup_config accept a config_dir; PipelexHub.get_optional_config added.
      • log.configure_if_unset guards against double init; report_validation_error works without pre-initialized config/logging.
      • ModelManager.setup accepts explicit path overrides; deep_update merges any Mapping.
    • Tests: new E2E to assert clean JSON stdout; unit tests for discipline side effects, doctor behavior, validation reporting, log defaults, and idempotent logging.
    • Badges: tests badge count updated.
    • Version bump to 0.30.0; changelog updated.

Written for commit 8b99246. Summary will update on new commits. Review in cubic

lchoquel and others added 2 commits May 25, 2026 13:46
* fix: route console logs and prints to stderr by default

The package-default `console_log_target` and `console_print_target` in
`pipelex/pipelex.toml` were set to "stdout", and the same value got baked
into the kit template (`pipelex/kit/configs/pipelex.toml`) that
`pipelex init` copies to `~/.pipelex/`. This contradicted the stated
intent of PR #452 — keep logs and rich prints off the data channel so
JSON-emitting commands like `pipelex-agent models --format json` stay
parseable for downstream tooling (e.g. `mthds-js`'s `PipelexRunner`,
which does `JSON.parse(stdout)`).

The bug was latent for stock installs because the agent-CLI JSON paths
happen not to log at INFO+, but surfaced for anyone who raised
`package_log_levels.pipelex` to DEBUG or added a setup-time log on a
command path.

Adds two regression guards:

- a unit test that loads the package-default `[pipelex.log_config]`
  directly with `tomli` and asserts both targets resolve to
  `ConsoleTarget.STDERR`
- an E2E test that spawns `pipelex-agent --log-level debug models
  --format json` in a hermetic HOME with the pipelex package log level
  bumped to DEBUG, then asserts `json.loads(stdout)` succeeds —
  protecting both the config value and any future `print()`/`log`
  routed to stdout on the command path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(logs): keep console_print_target on stdout (logs to stderr, prints to stdout)

Walks back the print_target half of ac858de — that flip broke
`pipelex show backends > out.txt` (empty file). Log target stays on
stderr (the actual fix for stdout-as-JSON-channel pollution); print
target reverts to stdout because the main pipelex CLI's human-facing
tables go through get_console() and must remain redirectable.

Test now pins both targets across both shipped TOMLs (package default
and kit template). CHANGELOG entry narrowed to log_target only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(agent-cli): enforce stderr for console targets to protect stdout JSON channel

* fix: enforce stderr for agent CLI logging and output discipline

* follow-ups

* follow-ups

* fix(doctor): scope --global to models, preserve partial reports, simplify discipline helper

- ModelManager.setup accepts explicit path kwargs so check_models can scope --global
  (previously it always read config_manager.X, ignoring the doctor's --global override).
- agent_doctor_cmd's PipelexConfigError arm now preserves the partial check tuples
  (telemetry/backends still reported) and marks models as skipped, matching the broken-
  config short-circuit; previously it called agent_error (NoReturn) and discarded them.
- apply_agent_cli_output_discipline simplified: drop the speculative log_level=None
  embedder-deference branch (no real consumer); always pin stderr. The helper now gates
  the hub call on PipelexHub.get_optional_instance so it's safe to call when no hub is
  installed (broken-config doctor path). setup_doctor_runtime drops its bool return and
  the surgical redirect guard that fell out of that branch.
- Human doctor renders "skipped" as yellow ⚠ instead of red ✗ when config is broken,
  with a "deferred until config errors are fixed" hint.
- JSON envelope adds a structured checks.models.skipped flag so downstream consumers
  can distinguish "models broken" from "models skipped due to config" without string-
  matching the message. Markdown renderer mirrors the change.
- Tests: fresh_log fixture stops RichHandler leaks onto the global root logger; new
  test_agent_cli_output_discipline module pins the helper's real side effects (the
  prior assertion-on-mock test would have shipped a typo regression green); regression
  test for the PipelexConfigError fallthrough; misleading docstring on
  test_returns_message_without_bootstrap rephrased to match the actual hub-state-
  isolation contract it pins.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: remove doctor-bootstrap review follow-up plans from wip/

Wave 1 and wave 2 plans were committed in 6972c96 and eee1fca respectively;
the wave 3 brief was an unstaged scratch doc. Their implementations have all
landed and they don't carry forward useful context — drop them so wip/ stays
focused on active design work rather than per-commit retrospective plans.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 25, 2026

Greptile Summary

This PR releases v0.30.0 with safer CLI output defaults. It changes:

  • Bumps the package version and changelog for v0.30.0.
  • Moves package log output defaults from stdout to stderr.
  • Pins agent CLI Rich log and print channels to stderr.
  • Updates doctor checks to preserve partial reports on config errors.
  • Adds tests for clean agent stdout, doctor behavior, and log configuration.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.
  • The latest update only adjusts badge metadata.
  • The previously reported doctor and agent-output issues are addressed in the current code.

Reviews (2): Last reviewed commit: "test-count" | Re-trigger Greptile

Comment thread pipelex/cli/commands/doctor_cmd.py
Comment thread pipelex/cli/agent_cli/commands/doctor_cmd.py
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 24 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread pipelex/cli/commands/doctor_cmd.py Outdated
lchoquel and others added 2 commits May 25, 2026 14:11
…gError; pin agent CLI discipline before check_models

- Human doctor (`do_doctor_cmd`) now catches `PipelexConfigError` from
  `setup_doctor_runtime` so a layered config that passes the on-disk shape
  check but fails Pydantic validation surfaces the translated message under
  the models section instead of falling into the outer "Unexpected error"
  handler. Mirrors the agent doctor's existing arm.
- Agent doctor (`agent_doctor_cmd`) now invokes
  `apply_agent_cli_output_discipline()` between `setup_doctor_runtime` and
  `check_models`. Since the bootstrap uses `log.configure_if_unset()`, an
  embedded reuse where logging is already pointed at stdout could let
  `check_models` log lines pollute the JSON envelope before the post-try
  discipline call fired. Calling discipline first closes that window.
- Regression tests added in `test_doctor_cmd.py` and `test_agent_doctor_cmd.py`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lchoquel lchoquel merged commit 386bc92 into main May 25, 2026
30 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators May 25, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant