Skip to content

Commit e481e38

Browse files
authored
Merge pull request #939 from Pipelex/release/v0.30.1
Release v0.30.1
2 parents 386bc92 + 62f0e94 commit e481e38

33 files changed

Lines changed: 678 additions & 281 deletions

.badges/tests.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"schemaVersion": 1,
33
"label": "tests",
4-
"message": "6111",
4+
"message": "6114",
55
"color": "blue",
66
"cacheSeconds": 300
77
}

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# Changelog
22

3+
## [v0.30.1] - 2026-05-26
4+
5+
### Fixed
6+
7+
- **`pipelex-agent` now silences every Python logger on stderr regardless of user TOML.** The agent CLI is machine-consumed: stdout is reserved for the structured success envelope (JSON / markdown) and stderr for the structured error envelope. Free-floating `log.*` calls — a `log.debug` from `telemetry_factory.py`, a `log.warning` from `validation_error_categorizer.py`, or an INFO/WARNING line from any third-party dep (`anthropic`, `httpx`, `botocore`, `openai`, anything a transitive dep configures) — would corrupt the stderr channel for downstream parsers (`mthds-js`'s `PipelexRunner` doing `JSON.parse(stderr)` on the validate hook). Two layers, defense-in-depth:
8+
- **Layer 1 — pin pipelex's own logs off via config.** `make_pipelex_for_agent_cli` injects `config_overrides` into `Pipelex.make()` that pin `default_log_level = OFF` and `package_log_levels.pipelex = OFF` from the very first `log.configure` call. A user setting `[pipelex.log_config.package_log_levels] pipelex = "DEBUG"` in `~/.pipelex/pipelex.toml` can no longer leak its own DEBUG/INFO/WARNING lines.
9+
- **Layer 2 — process-global cutoff that covers every logger.** New `silence_logging_for_agent_cli()` calls `logging.disable(sys.maxsize)` — a process-global threshold checked inside `Logger.isEnabledFor` BEFORE any per-logger level. No record gets created for any logger at any level (including custom levels above `CRITICAL`), regardless of which package emits or what level the user configured. Wired into the Typer `app_callback` so every subcommand — including `init` and `accept-gateway-terms`, which bypass `make_pipelex_for_agent_cli` — silences logging before any command body runs; idempotent per-call invocations remain inside `make_pipelex_for_agent_cli` and `agent_doctor_cmd` as belt-and-braces for direct library callers.
10+
11+
A new e2e regression test pins the contract by setting `anthropic`, `httpx`, `botocore`, `openai` to `DEBUG` in the user TOML and asserting both stdout and stderr stay clean.
12+
13+
### Changed
14+
15+
- **`pipelex-agent` no longer accepts `--log-level`.** Log suppression is unconditional by design — there is no verbosity setting on the agent CLI. The `log_level` parameter is removed from `make_pipelex_for_agent_cli()` and `apply_agent_cli_output_discipline()`, and the corresponding `ctx.obj["log_level"]` plumbing is gone from every caller. For verbose debugging, use the human `pipelex` CLI, which honors the user's TOML log config.
16+
17+
- **`pipelex/cli/commands/doctor_cmd.py::setup_doctor_runtime` now `deep_update`s `log_config_overrides` into the loaded config** (was a flat-merge that silently replaced nested dicts like `package_log_levels`). With the flat merge, pinning `package_log_levels.pipelex = OFF` for the agent doctor path would have wiped out all the third-party package levels (`anthropic`, `asyncio`, `botocore`, ...) shipped in the default config. The deep merge preserves them.
18+
19+
- **Removed `ctx: typer.Context` from 8 agent CLI commands that no longer used it.** `validate/{pipe,bundle,method}_cmd.py`, `inputs/{pipe,bundle,method}_cmd.py`, `models_cmd.py`, `check_model_cmd.py` had `ctx.obj["log_level"]` as their only ctx usage; with `--log-level` gone, the parameter became dead weight. The `run/` commands keep `ctx` because they still read `ctx.obj["runner"]`. Test callers (and the now-unused `agent_ctx` conftest fixture) updated to match.
20+
321
## [v0.30.0] - 2026-05-25
422

523
### Fixed

TODOS.md

Lines changed: 112 additions & 33 deletions
Large diffs are not rendered by default.

pipelex/cli/agent_cli/_agent_cli.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from typing_extensions import override
1010

1111
from pipelex.cli.agent_cli.commands.accept_gateway_terms_cmd import agent_accept_gateway_terms_cmd
12+
from pipelex.cli.agent_cli.commands.agent_cli_factory import silence_logging_for_agent_cli
1213
from pipelex.cli.agent_cli.commands.agent_output import CliOutputFormat, agent_error, set_agent_cli_error_format
1314
from pipelex.cli.agent_cli.commands.check_model_cmd import agent_check_model_cmd
1415
from pipelex.cli.agent_cli.commands.concept_cmd import concept_cmd
@@ -21,7 +22,6 @@
2122
from pipelex.cli.agent_cli.commands.pipe_cmd import pipe_cmd
2223
from pipelex.cli.agent_cli.commands.run.app import run_app
2324
from pipelex.cli.agent_cli.commands.validate.app import validate_app
24-
from pipelex.tools.log.log_levels import LogLevel
2525
from pipelex.tools.misc.package_utils import get_package_version
2626

2727

@@ -91,31 +91,35 @@ def app_callback(
9191
is_eager=True,
9292
),
9393
] = False,
94-
log_level: Annotated[
95-
str,
96-
typer.Option("--log-level", help="Log verbosity level (debug, verbose, info, warning, error, critical)."),
97-
] = "warning",
9894
runner: Annotated[
9995
str,
10096
typer.Option("--runner", help="Runner to use: 'pipelex' (local) or 'api' (remote MTHDS API)."),
10197
] = "pipelex",
10298
) -> None:
103-
"""Agent CLI callback - no logo, minimal output."""
99+
"""Agent CLI callback - no logo, minimal output.
100+
101+
Note: there is no ``--log-level`` flag. ``pipelex-agent`` is machine-consumed:
102+
stdout is reserved for the success envelope and stderr for the error envelope.
103+
Free-floating logs would corrupt those channels, so Python's logging system is
104+
cut off process-wide via ``silence_logging_for_agent_cli`` as the very first
105+
action in this callback — covering every subcommand invocation (including ones
106+
like ``init`` and ``accept-gateway-terms`` that bypass
107+
``make_pipelex_for_agent_cli``). The ``--version`` eager option short-circuits
108+
before this body runs, but its callback only does ``typer.echo`` + ``Exit`` and
109+
touches no log path. For verbose debugging, use the human ``pipelex`` CLI instead.
110+
"""
111+
# Process-global logging cutoff, armed BEFORE any command body runs and BEFORE any
112+
# error-format / runner-validation code below can route through ``log.*``. This is the
113+
# primary armor for the stdout/stderr discipline; the per-call invocations inside
114+
# ``make_pipelex_for_agent_cli`` and ``agent_doctor_cmd`` are kept as defense-in-depth
115+
# for direct library callers that bypass this Typer entry point.
116+
silence_logging_for_agent_cli()
104117
# Reset the error-format ContextVar at the single choke point every command passes through, so
105118
# a markdown command cannot leak markdown into a later JSON-only command in the same process.
106119
# --format / --error-format commands override this afterwards; JSON-only commands keep the JSON default.
107120
set_agent_cli_error_format(CliOutputFormat.JSON)
108121

109122
ctx.ensure_object(dict)
110-
try:
111-
ctx.obj["log_level"] = LogLevel(log_level.upper())
112-
except ValueError:
113-
valid_values = ", ".join(level.value.lower() for level in LogLevel)
114-
agent_error(
115-
f"Invalid log level '{log_level}'. Valid values: {valid_values}",
116-
"ArgumentError",
117-
)
118-
119123
try:
120124
ctx.obj["runner"] = RunnerType(runner)
121125
except ValueError:

0 commit comments

Comments
 (0)