Release v0.30.0#938
Merged
Merged
Conversation
* 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 SummaryThis PR releases v0.30.0 with safer CLI output defaults. It changes:
Confidence Score: 5/5This looks safe to merge.
Reviews (2): Last reviewed commit: "test-count" | Re-trigger Greptile |
There was a problem hiding this comment.
1 issue found across 24 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release v0.30.0
Bumps version from
0.29.1to0.30.0.Changelog
Fixed
console_log_targetpackage default is nowstderr(wasstdout). 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 parsespipelex/pipelex-agentstdout as JSON (e.g.mthds-js'sPipelexRunner) 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 raisedpackage_log_levels.pipelexto 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) thatpipelex initcopies to~/.pipelex/. Note:console_print_targetis intentionally left atstdout— the mainpipelexCLI 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-agentnow pins both console targets tostderrregardless of user config.make_pipelex_for_agent_cliinjectsconfig_overridesintoPipelex.make()that forceconsole_log_target = "stderr"andconsole_print_target = "stderr"from the very first log/print fired during init, so a user override of either knob in~/.pipelex/pipelex.tomlcan no longer leak diagnostics onto the agent CLI's JSON data channel. Defense-in-depth post-init calls tolog.redirect_to_stderr()andget_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 tostdoutandpackage_log_levels.pipelextoDEBUGand assertingjson.loads(stdout)still parses.Summary by cubic
Release v0.30.0 hardens
pipelex-agentso stdout stays clean JSON and flips package log defaults to stderr. The humanpipelexCLI keeps tables on stdout for redirects.console_log_targetnowstderrin package and kit;console_print_targetstaysstdout.stderrfrom the first init step and applies output discipline so JSON on stdout remains parseable even under user overrides.--globalby scoping model/backend paths to the provided config dir.checks.models.skippedand renders a warning icon.PipelexConfigErrorfrom bootstrap and shows the translated message under “Models” instead of a generic error.check_modelsto prevent early log leakage to stdout.ConfigLoader.load_configandPipelexHub.setup_configaccept aconfig_dir;PipelexHub.get_optional_configadded.log.configure_if_unsetguards against double init;report_validation_errorworks without pre-initialized config/logging.ModelManager.setupaccepts explicit path overrides;deep_updatemerges anyMapping.0.30.0; changelog updated.Written for commit 8b99246. Summary will update on new commits. Review in cubic