Skip to content

Commit 22883f0

Browse files
committed
agentgrep(fix[insights]): Bound persisted insight listings
why: Persisted insight listings could materialize millions of variant edges and the default text output looked like malformed JSON. Bounded pages, count-only explain output, and terminal summaries keep the CLI usable for humans while preserving explicit JSON and NDJSON for scripts. what: - Add bounded insight listing payloads, count APIs, MCP totals, and a confidence-order SQLite index. - Render DB, insights, and suggestions structured payloads as semantic human summaries by default. - Keep JSON and NDJSON machine modes explicit and cover the CLI contracts with regression tests and docs.
1 parent fec8cd7 commit 22883f0

14 files changed

Lines changed: 1197 additions & 55 deletions

File tree

‎docs/cli/insights/list.md‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,26 @@
22

33
# agentgrep insights list
44

5-
List persisted similarity edges and omission findings. This command
6-
does not run new analysis.
5+
List a bounded page of persisted similarity edges and omission
6+
findings. By default this prints a terminal summary with sampled rows;
7+
use `--json` or `--ndjson` when stdout must be machine-readable. This
8+
command does not run new analysis. Use `agentgrep insights explain` for
9+
cheap counts without returning row samples.
710

811
## Examples
912

10-
List all persisted insights:
13+
List a small persisted-insight sample:
1114

1215
```console
1316
$ agentgrep insights list
1417
```
1518

19+
Change the per-kind row limit:
20+
21+
```console
22+
$ agentgrep insights list --limit 10
23+
```
24+
1625
List only omission findings as JSON:
1726

1827
```console

‎docs/cli/suggestions/list.md‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
# agentgrep suggestions list
44

5-
List persisted suggestion artifacts. When `--target` is provided,
6-
agentgrep first creates review-only suggestions from open omission
7-
findings for that target.
5+
List persisted suggestion artifacts. By default this prints a terminal
6+
summary; use `--json` or `--ndjson` when stdout must be
7+
machine-readable. When `--target` is provided, agentgrep first creates
8+
review-only suggestions from open omission findings for that target.
89

910
## Examples
1011

‎docs/insights/index.md‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,22 @@ Analyze similarity and omission evidence:
2626
$ agentgrep insights analyze
2727
```
2828

29-
List the stored evidence:
29+
List a bounded human summary of stored evidence:
3030

3131
```console
32-
$ agentgrep insights list --json
32+
$ agentgrep insights list --limit 10
33+
```
34+
35+
Emit the same evidence page as JSON:
36+
37+
```console
38+
$ agentgrep insights list --limit 10 --json
39+
```
40+
41+
Get cheap persisted-insight counts without returning evidence rows:
42+
43+
```console
44+
$ agentgrep insights explain --json
3345
```
3446

3547
## Similarity

‎docs/mcp/tools.md‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,11 @@ findings, and suggestion counts.
153153
```
154154

155155
**Use when** you need persisted deterministic insight artifacts from
156-
the DB index. This tool lists existing artifacts and does not
157-
run a new insight job.
156+
the DB index. This tool lists a bounded page of existing artifacts and
157+
does not run a new insight job.
158158

159-
**Returns:** variant edges and omission findings.
159+
**Returns:** total counts, truncation flags, and sampled variant edges
160+
and omission findings.
160161

161162
```{fastmcp-tool-input} insights_list
162163
```

‎src/agentgrep/__init__.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ def build_description(
289289
(
290290
"agentgrep insights",
291291
"agentgrep insights analyze --kind similarity",
292-
"agentgrep insights list --json",
292+
"agentgrep insights list --limit 10 --json",
293293
),
294294
),
295295
(
@@ -403,7 +403,7 @@ def build_description(
403403
"agentgrep insights",
404404
"agentgrep insights analyze --kind similarity",
405405
"agentgrep insights analyze --kind omissions --target AGENTS.md",
406-
"agentgrep insights list --json",
406+
"agentgrep insights list --limit 10 --json",
407407
"agentgrep insights explain",
408408
),
409409
),

‎src/agentgrep/cli/parser.py‎

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
InsightsKind = t.Literal["similarity", "omissions", "all"]
5555
SuggestionsAction = t.Literal["list", "show", "render"]
5656

57+
DEFAULT_INSIGHTS_LIST_LIMIT = 50
58+
5759
__all__ = [
5860
"CaseMode",
5961
"DbArgs",
@@ -203,6 +205,7 @@ class InsightsArgs:
203205
output_mode: OutputMode
204206
color_mode: ColorMode = "auto"
205207
progress_mode: ProgressMode = "never"
208+
limit: int = DEFAULT_INSIGHTS_LIST_LIMIT
206209

207210

208211
@dataclasses.dataclass(slots=True)
@@ -214,6 +217,7 @@ class SuggestionsArgs:
214217
suggestion_id: str | None
215218
target: str | None
216219
output_mode: OutputMode
220+
color_mode: ColorMode = "auto"
217221

218222

219223
@dataclasses.dataclass(slots=True)
@@ -745,6 +749,12 @@ def create_parser(
745749
default="all",
746750
help="Insight family to list",
747751
)
752+
_ = insights_list_parser.add_argument(
753+
"--limit",
754+
type=int,
755+
default=DEFAULT_INSIGHTS_LIST_LIMIT,
756+
help=f"Maximum rows to return per insight family (default: {DEFAULT_INSIGHTS_LIST_LIMIT})",
757+
)
748758
add_output_mode_options(insights_list_parser, allow_ui=False)
749759

750760
insights_explain_parser = insights_subparsers.add_parser(
@@ -1012,7 +1022,7 @@ def parse_args(
10121022
with configured_color_environment(color_mode):
10131023
bundle.suggestions_parser.print_help()
10141024
return None
1015-
return _build_suggestions_args(namespace)
1025+
return _build_suggestions_args(namespace, color_mode=color_mode)
10161026

10171027
agents = parse_agents(t.cast("list[str]", namespace.agent))
10181028
output_mode = parse_output_mode(namespace)
@@ -1132,6 +1142,10 @@ def _build_insights_args(
11321142
if action == "analyze" and kind == "omissions" and target is None:
11331143
with configured_color_environment(color_mode):
11341144
bundle.insights_parser.error("--target is required for omission insight analysis")
1145+
limit = t.cast("int", getattr(namespace, "limit", DEFAULT_INSIGHTS_LIST_LIMIT))
1146+
if action == "list" and limit < 1:
1147+
with configured_color_environment(color_mode):
1148+
bundle.insights_parser.error("--limit must be greater than 0")
11351149
return InsightsArgs(
11361150
action=action,
11371151
db_path=t.cast("str | None", getattr(namespace, "db_path", None)),
@@ -1140,17 +1154,23 @@ def _build_insights_args(
11401154
output_mode=parse_output_mode(namespace),
11411155
color_mode=color_mode,
11421156
progress_mode=t.cast("ProgressMode", getattr(namespace, "progress", "never")),
1157+
limit=limit,
11431158
)
11441159

11451160

1146-
def _build_suggestions_args(namespace: argparse.Namespace) -> SuggestionsArgs:
1161+
def _build_suggestions_args(
1162+
namespace: argparse.Namespace,
1163+
*,
1164+
color_mode: ColorMode,
1165+
) -> SuggestionsArgs:
11471166
"""Build :class:`SuggestionsArgs` from a parsed argparse namespace."""
11481167
return SuggestionsArgs(
11491168
action=t.cast("SuggestionsAction", namespace.suggestions_action),
11501169
db_path=t.cast("str | None", getattr(namespace, "db_path", None)),
11511170
suggestion_id=t.cast("str | None", getattr(namespace, "suggestion_id", None)),
11521171
target=t.cast("str | None", getattr(namespace, "target", None)),
11531172
output_mode=parse_output_mode(namespace),
1173+
color_mode=color_mode,
11541174
)
11551175

11561176

0 commit comments

Comments
 (0)