Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ agentrace stats --json # aggregate, machine-readable

Point it somewhere else with `--dir` or at one file with `--file`.

`show --max N` limits each prompt and result to at most `N` characters (default
4000). `N` must be a non-negative integer; zero hides the text, while negative
values are usage errors (exit code 2).

## Install

**PyPI:** https://pypi.org/project/agentrace-cli/
Expand Down
14 changes: 13 additions & 1 deletion agentrace/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,13 @@ def cmd_stats(args) -> int:
return 0


def _nonnegative_int(value: str) -> int:
number = int(value)
if number < 0:
raise argparse.ArgumentTypeError("must be a non-negative integer")
return number


def _existing_file(value: str) -> str:
if not Path(value).is_file():
raise argparse.ArgumentTypeError(f"not a file: {value}")
Expand All @@ -199,7 +206,12 @@ def main(argv: list[str] | None = None) -> int:

s = sub.add_parser("show", help="read one run in full")
s.add_argument("id", help="tool_use_id or its last 8 chars")
s.add_argument("--max", type=int, default=4000, help="truncate long text")
s.add_argument(
"--max",
type=_nonnegative_int,
default=4000,
help="maximum characters per prompt/result (non-negative; default: 4000)",
)
s.set_defaults(func=cmd_show)

st = sub.add_parser("stats", help="aggregate stats")
Expand Down
34 changes: 34 additions & 0 deletions tests/test_show_limit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import pytest

from agentrace import cli


@pytest.mark.parametrize("value", ["-1", "-5"])
def test_negative_limit_rejected_before_loading(value, monkeypatch, capsys):
def unexpected_load(args):
pytest.fail("invalid --max must be rejected before loading transcripts")

monkeypatch.setattr(cli, "_load", unexpected_load)
with pytest.raises(SystemExit) as exc:
cli.main(["show", "abc", "--max", value])
assert exc.value.code == 2
captured = capsys.readouterr()
assert "--max" in captured.err
assert "non-negative" in captured.err
assert captured.out == ""


@pytest.mark.parametrize(
"options, expected",
[([], 4000), (["--max", "0"], 0), (["--max", "1"], 1), (["--max", "100"], 100)],
)
def test_nonnegative_limit_and_default(options, expected, monkeypatch):
seen = []

def show(args):
seen.append(args.max)
return 0

monkeypatch.setattr(cli, "cmd_show", show)
assert cli.main(["show", "abc", *options]) == 0
assert seen == [expected]
Loading