mcp: add compact run and result navigation#330
Conversation
The API module intended to declare public exports, but used a plain all variable instead of Python's __all__ convention. Fix the export declaration separately so later run and result API refactors do not carry an unrelated module-level cleanup. Signed-off-by: Mikhail Zayats <mikhail.zayats@oktetlabs.ru>
158c578 to
9693777
Compare
| from datetime import datetime, timedelta | ||
|
|
||
|
|
||
| class RunCompromisedDetails(BaseModel): |
There was a problem hiding this comment.
PR #324 introduces a typed DTO layer in bublik/core/run/dto.py that covers the same domain structures — RunDetailsResult, RunStatsResult, RunCompromisedDetails, RunRevision, and others — using dataclasses. This PR defines equivalent models in bublik/mcp/run/models.py using Pydantic. If both are merged, the codebase will have two parallel definitions of the same entities with no single source of truth. It may be worth coordinating with #324 to avoid the duplication — the MCP Pydantic models could potentially be built on top of the DTO layer rather than alongside it.
There was a problem hiding this comment.
I've made changes and removed redundant pydantic models and run formatting via ruff like in this PR #331
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
|
|
||
| from pydantic import AnyUrl, BaseModel, ConfigDict, Field, RootModel | ||
|
|
||
|
|
There was a problem hiding this comment.
This change is unrelated to the MCP navigation workflow and should not be included in this commit. Please remove it to keep the architectural change focused, consistent, and reviewable.
Split run and result API views into dedicated modules to keep entity-specific code isolated and easier to evolve independently. Signed-off-by: Mikhail Zayats <mikhail.zayats@oktetlabs.ru>
Replace dict-based service responses with typed DTOs to introduce explicit and structured data contracts across service boundaries and move serialization to API/MCP boundary to improve separation of concerns between service layer and API/MCP layers. Signed-off-by: Mikhail Zayats <mikhail.zayats@oktetlabs.ru>
Ensure consistency between OpenAPI schemas and API responses by introducing explicit request/response serializers and binding them via drf-spectacular. Signed-off-by: Mikhail Zayats <mikhail.zayats@oktetlabs.ru>
Ensure consistency between OpenAPI schemas and API responses by introducing explicit request/response serializers and binding them via drf-spectacular. Signed-off-by: Mikhail Zayats <mikhail.zayats@oktetlabs.ru>
e1073d7 to
1bf28e6
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>
Link: https://peps.python.org/pep-0257/ Link: ts-factory#331 Signed-off-by: Danil Kostromin <danil.kostromin@icloud.com>
1bf28e6 to
4551d96
Compare
Changed to |
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