mcp: add compact run and result navigation#330
Conversation
158c578 to
9693777
Compare
34daf38 to
5eb5350
Compare
ol-nata
left a comment
There was a problem hiding this comment.
Please use a more goal-oriented commit summary: replace mcp: add compact run and result navigation with something like mcp: enforce structured run/result navigation workflow to prevent incorrect tool usage
1bf28e6 to
4551d96
Compare
Changed to |
2550b81 to
9f45117
Compare
| meta_results__meta__type='result', | ||
| meta_results__meta__value__in=abnormal_statuses, | ||
| ), | ||
| ) |
There was a problem hiding this comment.
This duplicates the existing Meta.abnormal / abnormal() helper in core/run/stats.py, which already encodes the same status set. Could we reuse Meta.abnormal here instead of resolving the statuses independently via discover_statuses? Otherwise the two definitions can drift apart over time.
|
|
||
| page = 1 | ||
| if pagination.previous: | ||
| page = int(pagination.previous.split('=')[1]) + 1 |
There was a problem hiding this comment.
nit: this recovers the current page by parsing pagination.previous ("page=N") back into an int. The resolved page is already computed in _get_run_leaf_results/PaginatedResult.paginate_queryset, just not passed along. Could it be threaded through as an explicit field on RunLeafResultsPayload/RunLeafPagination instead, so this doesn't depend on the string format of previous?
c815906 to
f213ba6
Compare
PaginatedResult.paginate_queryset already resolves the current page number but discarded it, leaving consumers to recover it from the 'next'/'previous' URL strings. Add it as an explicit 'page' field on the returned pagination dict so callers can read it directly. Signed-off-by: Danil Kostromin <danil.kostromin@icloud.com>
ec992ea to
04bfb84
Compare
The previous commit added a 'page' field to the dict returned by PaginatedResult.paginate_queryset, but RunListPagination is a fixed-field dataclass built from that dict via RunService.list_runs (RunListPagination(**paginated_runs['pagination'])). Without a matching field it raises TypeError on the unexpected 'page' keyword. Add 'page' to keep the DTO consistent with the shared pagination shape. Follow-up to: f8bb70e Signed-off-by: Danil Kostromin <danil.kostromin@icloud.com>
5640030 to
39da14b
Compare
Replace the fragmented run metadata tools and the ambiguous direct-child `list_results` interface with two validated Markdown workflows. `get_run_overview` combines run metadata with the recursive statistics tree and can reduce it to unexpected leaves. `get_run_leaf_results` accepts an aggregate test result ID from that overview and delegates concrete execution filtering and pagination to the existing result service. This gives MCP clients a compact way to inspect large run trees without reconstructing UI lazy-loading semantics, while preserving strict payload validation before rendering. Issue: ts-factory#326 Issue: ts-factory#327 Signed-off-by: Danil Kostromin <danil.kostromin@icloud.com>
39da14b to
e72b9ba
Compare
Stacked on top of #324
Replace the fragmented run metadata tools and the ambiguous direct-child
list_resultsinterface with two validated Markdown workflows for MCP clients.What changed
This PR introduces two higher-level run navigation tools:
get_run_overviewget_run_leaf_resultsTogether they replace the previous flow where clients had to call separate run
metadata/stat/source tools and manually reconstruct how to navigate from a run
tree node to concrete test executions.
New tools
get_run_overviewReturns a complete Markdown overview for a run, including:
The tool also supports:
requirements: semicolon-separated requirement filterunexpected_only: return only leaf tests containing unexpected or abnormal resultsEach test row includes a Result ID that can be passed directly to
get_run_leaf_results.get_run_leaf_resultsReturns paginated concrete executions represented by one test leaf from
get_run_overview.The input is intentionally an aggregate test Result ID from the overview, not an
individual execution ID. The tool validates that the ID points to a real test
leaf before resolving executions.
It supports two usage modes:
unexpected_only=true: common failure-investigation mode, returning onlyunexpected or abnormal executions
requirementsresults, for examplePASSED;FAILED;SKIPPED;KILLED;CORED;FAKED;INCOMPLETEresult_properties, for exampleexpected;unexpected;not_rununexpected_onlyis mutually exclusive with the advanced filters.Why this is better
The old MCP interface exposed lower-level pieces of the UI model. Clients had to
combine run details, source, stats, and direct-child result listing themselves,
while also knowing how Bublik lazy-loads the run tree.
The new flow is explicit:
get_run_overview(run_id)to inspect the run and find interesting test leaves.get_run_leaf_results(leaf_result_id)to inspect concrete executions.This makes MCP usage more reliable and cheaper for large runs because clients no
longer need to fetch or reason over unrelated execution details.
Token impact
Estimated token count changes:
Validation and rendering
The new run payloads are validated with strict Pydantic models before Markdown
rendering. This keeps the MCP output compact and human-readable while still
catching unexpected service payload changes early.
Issue: #326
Issue: #327