fix(cli): fix session show/list JSON output to not redact input messages (#6436)

ISSUES CLOSED: #6436
This commit is contained in:
2026-04-09 23:38:25 +00:00
committed by Forgejo
parent 581dff6b43
commit b92f0270c2
4 changed files with 55 additions and 0 deletions
+10
View File
@@ -39,6 +39,11 @@ Feature: Session CLI commands
Then the session CLI output should be valid JSON
And the session CLI JSON should contain "sessions"
Scenario: List sessions JSON includes token usage counts
Given there are mocked existing sessions
When I run session CLI list with --format json
Then the session CLI JSON list token usage should include counts
# Show command tests
Scenario: Show session with valid ID
Given there is a mocked session with messages
@@ -59,6 +64,11 @@ Feature: Session CLI commands
When I run session CLI show with --format json
Then the session CLI output should be valid JSON
Scenario: Show session JSON includes token usage counts
Given there is a mocked session with messages
When I run session CLI show with --format json
Then the session CLI JSON token usage should include counts
Scenario: Show session with invalid ID
When I run session CLI show with an invalid session ID
Then the session CLI should exit with error
+38
View File
@@ -514,6 +514,44 @@ def step_json_contains_key(context: Context, key: str) -> None:
assert key in data, f"Key '{key}' not found in JSON: {data}"
@then("the session CLI JSON token usage should include counts")
def step_json_show_token_usage_counts(context: Context) -> None:
parsed = json.loads(context.result.output)
data = _unwrap_envelope(parsed)
token_usage = data.get("token_usage")
assert isinstance(token_usage, dict), (
f"token_usage missing or not an object: {token_usage}"
)
_assert_token_usage_counts_are_ints(token_usage)
@then("the session CLI JSON list token usage should include counts")
def step_json_list_token_usage_counts(context: Context) -> None:
parsed = json.loads(context.result.output)
data = _unwrap_envelope(parsed)
sessions = data.get("sessions")
assert isinstance(sessions, list), f"sessions missing or not a list: {sessions}"
for index, session in enumerate(sessions):
token_usage = session.get("token_usage")
assert isinstance(token_usage, dict), (
f"token_usage missing for session {index}: {token_usage}"
)
_assert_token_usage_counts_are_ints(token_usage)
def _assert_token_usage_counts_are_ints(token_usage: dict[str, Any]) -> None:
input_tokens = token_usage.get("input_tokens")
output_tokens = token_usage.get("output_tokens")
assert isinstance(input_tokens, int), (
f"input_tokens should be int, got {input_tokens!r}"
)
assert isinstance(output_tokens, int), (
f"output_tokens should be int, got {output_tokens!r}"
)
assert input_tokens != "***REDACTED***", "input_tokens should not be redacted"
assert output_tokens != "***REDACTED***", "output_tokens should not be redacted"
@then("the session CLI should exit with error")
def step_exit_with_error(context: Context) -> None:
assert context.result.exit_code != 0, (
+5
View File
@@ -133,6 +133,11 @@ def _session_list_dict(sessions: list[Session]) -> dict[str, Any]:
"actor": s.actor_name or "(none)",
"messages": s.message_count,
"updated": s.updated_at.isoformat(),
"token_usage": {
"input_tokens": s.token_usage.input_tokens,
"output_tokens": s.token_usage.output_tokens,
"estimated_cost": f"${s.token_usage.estimated_cost:.4f}",
},
}
)
+2
View File
@@ -44,6 +44,8 @@ _FALSE_POSITIVE_KEYS: set[str] = {
"token_count",
"token_limit",
"token_usage",
"input_tokens",
"output_tokens",
"max_tokens",
"total_tokens",
"prompt_tokens",