Добавить подсказки следующего шага stage-loop
This commit is contained in:
parent
a3378a3d52
commit
37d33bd6e6
|
|
@ -139,6 +139,8 @@ It stores the GUI review under `artifacts/domain_runs/stage_agent_loops/<stage_i
|
|||
- `continue_repair_from_gui_review_p1` when the run is semantically usable but still noisy, over-broad, or poorly layered;
|
||||
- `manual_gui_confirmation_or_stage_close` when the GUI run is clean enough for final human confirmation.
|
||||
|
||||
`stage_loop_summary.json` also includes `next_step_guidance.command_templates`, so the next operator or agent pass can continue from machine-readable commands instead of re-inferring the workflow from prose.
|
||||
|
||||
It also writes `stage_repair_handoff.md/json` next to the stage summary. That handoff is the preferred input for the next coder pass: it lists primary repair targets and sample user-facing failures without forcing the coder to reread the entire GUI conversation first.
|
||||
|
||||
To prepare the next repair iteration from that handoff, run:
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ def build_stage_summary(stage_manifest: dict[str, Any], loop_dir: Path) -> dict[
|
|||
next_action = "user_decision_required"
|
||||
else:
|
||||
next_action = "continue_autonomous_or_fix_blocker"
|
||||
return {
|
||||
summary = {
|
||||
"schema_version": STAGE_SUMMARY_SCHEMA_VERSION,
|
||||
"stage_id": stage_manifest["stage_id"],
|
||||
"module_name": stage_manifest.get("module_name"),
|
||||
|
|
@ -230,6 +230,60 @@ def build_stage_summary(stage_manifest: dict[str, Any], loop_dir: Path) -> dict[
|
|||
"save_autorun_on_accept": bool(stage_manifest.get("save_autorun_on_accept", True)),
|
||||
"updated_at": now_iso(),
|
||||
}
|
||||
summary["next_step_guidance"] = build_next_step_guidance(next_action)
|
||||
return summary
|
||||
|
||||
|
||||
def build_next_step_guidance(next_action: str) -> dict[str, Any]:
|
||||
command_by_action: dict[str, list[str]] = {
|
||||
"continue_repair_from_gui_review_p0": [
|
||||
"python scripts/stage_agent_loop.py prepare-repair --manifest <stage_manifest.json>",
|
||||
"python scripts/stage_agent_loop.py run-repair --manifest <stage_manifest.json> --dry-run",
|
||||
],
|
||||
"continue_repair_from_gui_review_p1": [
|
||||
"python scripts/stage_agent_loop.py prepare-repair --manifest <stage_manifest.json>",
|
||||
"python scripts/stage_agent_loop.py run-repair --manifest <stage_manifest.json> --dry-run",
|
||||
],
|
||||
"execute_repair_without_dry_run_or_review_command": [
|
||||
"python scripts/stage_agent_loop.py run-repair --manifest <stage_manifest.json>",
|
||||
],
|
||||
"rerun_same_stage_or_gui_and_ingest_result": [
|
||||
"rerun the same GUI/session or stage semantic pack",
|
||||
"python scripts/stage_agent_loop.py ingest-gui-run --manifest <stage_manifest.json> --run-id assistant-stage1-<new_id>",
|
||||
],
|
||||
"rerun_or_inspect_repair_targets": [
|
||||
"inspect repair_execution_summary.json and repair_targets.json",
|
||||
"rerun the same GUI/session if the patch intentionally made no code changes",
|
||||
],
|
||||
"user_or_architecture_decision_required": [
|
||||
"inspect repair_coder_result.json and decide whether to change scope, architecture, or acceptance bounds",
|
||||
],
|
||||
"inspect_repair_execution_result": [
|
||||
"inspect repair_execution_summary.json before continuing",
|
||||
],
|
||||
"manual_gui_confirmation": [
|
||||
"run or review the saved AGENT autorun in the GUI for final human confirmation",
|
||||
],
|
||||
"manual_gui_confirmation_or_stage_close": [
|
||||
"review the latest GUI run visually; close the stage only if the user-facing answers are acceptable",
|
||||
],
|
||||
"stage_closed_without_manual_confirmation": [
|
||||
"archive the stage artifacts and continue to the next module",
|
||||
],
|
||||
"user_decision_required": [
|
||||
"read stage_loop_handoff.md and resolve the recorded user decision point",
|
||||
],
|
||||
"continue_autonomous_or_fix_blocker": [
|
||||
"inspect stage_loop_handoff.md and rerun stage_agent_loop.py run after resolving the blocker",
|
||||
],
|
||||
"inspect_gui_review_status": [
|
||||
"inspect run_review.md and repair_targets.json manually",
|
||||
],
|
||||
}
|
||||
return {
|
||||
"next_action": next_action,
|
||||
"command_templates": command_by_action.get(next_action, ["inspect stage_loop_handoff.md"]),
|
||||
}
|
||||
|
||||
|
||||
def build_stage_handoff_markdown(summary: dict[str, Any]) -> str:
|
||||
|
|
@ -258,6 +312,19 @@ def build_stage_handoff_markdown(summary: dict[str, Any]) -> str:
|
|||
lines.extend(["", "## Acceptance invariants"])
|
||||
invariants = summary.get("acceptance_invariants") or []
|
||||
lines.extend([f"- {item}" for item in invariants] if invariants else ["- domain loop gate + analyst verdict"])
|
||||
next_step_guidance = (
|
||||
summary.get("next_step_guidance")
|
||||
if isinstance(summary.get("next_step_guidance"), dict)
|
||||
else {}
|
||||
)
|
||||
if next_step_guidance:
|
||||
lines.extend(["", "## Next Step Guidance"])
|
||||
commands = (
|
||||
next_step_guidance.get("command_templates")
|
||||
if isinstance(next_step_guidance.get("command_templates"), list)
|
||||
else []
|
||||
)
|
||||
lines.extend([f"- `{item}`" for item in commands] if commands else ["- inspect stage_loop_handoff.md"])
|
||||
latest_gui_review = summary.get("latest_gui_review") if isinstance(summary.get("latest_gui_review"), dict) else {}
|
||||
if latest_gui_review:
|
||||
lines.extend(
|
||||
|
|
@ -369,6 +436,7 @@ def build_repair_execution_stage_summary(
|
|||
"updated_at": now_iso(),
|
||||
}
|
||||
)
|
||||
base["next_step_guidance"] = build_next_step_guidance(next_action)
|
||||
return base
|
||||
|
||||
|
||||
|
|
@ -495,6 +563,7 @@ def build_gui_review_stage_summary(
|
|||
},
|
||||
}
|
||||
)
|
||||
base["next_step_guidance"] = build_next_step_guidance(next_action)
|
||||
latest_repair_validation = build_latest_repair_validation(
|
||||
previous_summary=previous_summary,
|
||||
review=review,
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ class StageAgentLoopTests(unittest.TestCase):
|
|||
self.assertEqual(summary["loop_final_status"], "accepted")
|
||||
self.assertTrue(summary["manual_confirmation_required"])
|
||||
self.assertEqual(summary["next_action"], "manual_gui_confirmation")
|
||||
self.assertIn("GUI", summary["next_step_guidance"]["command_templates"][0])
|
||||
|
||||
def test_build_stage_summary_continues_when_loop_is_partial(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
|
|
@ -203,6 +204,7 @@ class StageAgentLoopTests(unittest.TestCase):
|
|||
self.assertEqual(summary["next_action"], "continue_repair_from_gui_review_p0")
|
||||
self.assertFalse(summary["accepted_gate"])
|
||||
self.assertEqual(summary["latest_gui_review"]["repair_targets_count"], 1)
|
||||
self.assertIn("prepare-repair", summary["next_step_guidance"]["command_templates"][0])
|
||||
|
||||
def test_gui_review_stage_summary_links_post_repair_validation(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
|
|
@ -451,6 +453,7 @@ class StageAgentLoopTests(unittest.TestCase):
|
|||
self.assertEqual(execution_summary["next_action"], "execute_repair_without_dry_run_or_review_command")
|
||||
self.assertTrue(stage_summary["latest_repair_execution"]["dry_run"])
|
||||
self.assertEqual(stage_summary["next_action"], "execute_repair_without_dry_run_or_review_command")
|
||||
self.assertIn("run-repair", stage_summary["next_step_guidance"]["command_templates"][0])
|
||||
|
||||
def test_resolve_stage_repair_iteration_auto_prepares_from_handoff(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
|
|
|
|||
Loading…
Reference in New Issue