Files
cleveragents-core/tools/controller/mcp/__init__.py
T
drew eebb5718a8 feat(controller): Phase 1a — 5 response-builder MCP servers
Per-attempt MCP subprocesses that enforce V1 contract invariants at
construction time. Worker LLM calls builder tools incrementally; the
MCP validates each call against the schema + cross-field invariants;
`{role}_finalize()` emits canonical Pydantic-validated JSON to stdout
for the worker controller to read (Phase 1c). Defense-in-depth: the
controller strict-parses whatever finalize emits.

Builders shipped:

- reviewer_builder: 9 tools. Auto-acks all CISummary gates as passed
  at start; reviewer only calls record_gate to discuss specifics.
  reviewer_override_gate requires ≥20-char justification. Approve
  with any failed gate is refused with an actionable error pointing
  at the override path. Request-changes requires ≥1 blocking issue.
  Verdict-vs-blocking-issues invariant checked at finalize.

- implementer_builder: 7 tools. Outcome-specific finalize invariants:
  resolved → ≥1 commit + ≥1 file; blocked → ≥1 blocker; noop → no
  commits/files/blockers.

- estimator_builder: 4 tools. Lightweight; requires
  recommended_tier + confidence + reasoning at finalize. Reasoning
  capped at 2048 chars.

- conflict_resolver_builder: 8 tools. outcome='resolved' requires
  new_head_sha + ≥1 commit + ≥1 file. resolution_strategy enum-checked.

- summarizer_builder: 3 tools. Summary 50-2000 chars (enforced at
  MCP layer and Pydantic).

Shared infrastructure:

- _builder_base.py: BuilderState dataclass + invariant guard helpers
  (require_started / require_not_finalized) + audit-record-with-summary
  + finalize_and_emit (validates against Pydantic model class,
  emits canonical JSON to stdout, marks finalized).

41 builder tests in test_mcp_builders.py (happy paths + every
invariant + outcome-specific paths + audit summarization + JSON
round-trip through Pydantic strict-parse). Plus the existing 62
Phase-0 tests. 103 controller tests total. Full auto_agents suite
(2465 tests) still passes.
2026-05-18 11:09:40 -04:00

22 lines
868 B
Python

"""Per-role response-builder MCP servers.
Each builder MCP is spawned per-attempt by the worker controller
(plan v9 decision: per-attempt subprocess). The worker (an OpenCode
LLM session) invokes the builder's tools to construct its response
piece-by-piece; the MCP validates each call against the V1 contract
and refuses invalid ones. ``{role}_finalize()`` emits the canonical
JSON output that the worker controller reads + strict-parses as
defense in depth.
Layout:
- ``_builder_base.py`` — shared builder state + invariant decorators.
- ``reviewer_builder.py`` etc. — per-role server modules.
Each server module is runnable as a script:
uv run python tools/controller/mcp/reviewer_builder.py
This is what the worker controller invokes per-attempt.
"""
from . import _builder_base # re-exported for tests; not for direct use
__all__ = ["_builder_base"]