Originally created by: Thanatos9404
Builds on [#68], which builds on [#67]. Merge those first.
Problem
Line-based selection treats JSON as lines. For an 80-issue gh issue list --json result, it kept a window around the matching issue and silently dropped the rest. Agents use list results to decide what to do next, so missing items are worse than short ones.
What changes
llmslim/_json_output.py, used by llmslim proxy and LLMSlimToolOutputMiddleware whenever a long tool result is JSON with a list:
- The list: it finds the largest list, at the top level or inside an envelope like
{"total_count": .., "items": [...]}. The envelope's other fields are kept.
- Related items stay whole, ranked by the words they share with the call, using up to half the budget.
- Every other item is one compact line. It tries tighter levels until all items fit:
- strings cut to 80 characters, nested lists shown as
[n items], nested objects as a few short fields;
- strings cut to 40 characters;
- identity fields only: id, number, key, name, title, state, status, type, dates, url, path.
- Only if even identity fields don't fit, items are dropped from the middle (never related ones), with a line naming them:
… [163 more items not shown: 4018, 4019, …].
- The note now says what was kept: "every list item with its short fields, and the items related to the call whole".
Non-JSON output, including log lines that merely start with [, takes the existing line-based path.
Result
For an 80-issue GitHub list asked about "refund rounding":
- Before: 3,816 tokens, a window of about 12 issues.
- After: 3,108 tokens with all 80 issues listed (number, title, state, date) and the refund issue whole.
Tests
tests/test_json_output.py has 13 tests. They cover:
- every item kept, with the related one whole;
- the levels tried in order;
- dropping from the middle, with a marker that names and counts the dropped items;
- envelopes;
- non-JSON, small and scalar inputs left to the line path;
- determinism;
- the note text;
- JSON printed by
Bash going through the proxy.
The full suite passes: 1,824. Ruff is clean, and mypy shows no errors in the new module.
Originally posted by: vercel[bot]
The latest updates on your projects. Learn more about Vercel for GitHub.
Ticket changed by: Thanatos9404