fix: strengthen goal patch repair routing
This commit is contained in:
@@ -299,10 +299,10 @@ def validate_write_output(text: str) -> str:
|
||||
def patch_repair_attempts() -> int:
|
||||
"""Return the bounded number of chances to repair an invalid model diff."""
|
||||
try:
|
||||
configured = int(os.environ.get("CASAN_GOAL_PATCH_REPAIR_ATTEMPTS", "1"))
|
||||
configured = int(os.environ.get("CASAN_GOAL_PATCH_REPAIR_ATTEMPTS", "2"))
|
||||
except ValueError:
|
||||
configured = 1
|
||||
return min(max(configured, 0), 1)
|
||||
configured = 2
|
||||
return min(max(configured, 0), 3)
|
||||
|
||||
|
||||
def patch_output_tokens() -> int:
|
||||
@@ -354,14 +354,23 @@ def repair_write_output(model: str, original_prompt: str, invalid_output: str, c
|
||||
"Every hunk must be complete and the patch must pass `git apply --check`. Do not emit `index` lines, placeholder hashes, commentary, plans, summaries, or side effects. Preserve the original objective and workspace restrictions.\n\n"
|
||||
f"ORIGINAL CONTRACT:\n{original_prompt}\n\nPREVIOUS INVALID RESPONSE:\n{invalid_output[:8000]}"
|
||||
)
|
||||
candidates = patch_repair_models(model)
|
||||
candidate = candidates[0] if candidates else model
|
||||
ok, output, metadata, reason = call_model(candidate, repair_prompt, candidate.startswith(("openai:", "anthropic:", "openai-compatible:")), max_output_tokens=patch_output_tokens())
|
||||
metadata = dict(metadata)
|
||||
metadata["repair_model"] = candidate
|
||||
if not ok:
|
||||
return False, "", metadata, f"goal_patch_repair_failed:{reason}"
|
||||
return True, output, metadata, "ok"
|
||||
candidates = patch_repair_models(model)[:patch_repair_attempts()]
|
||||
last_metadata, last_reason = {}, "goal_patch_missing"
|
||||
for candidate in candidates:
|
||||
ok, output, metadata, reason = call_model(candidate, repair_prompt, candidate.startswith(("openai:", "anthropic:", "openai-compatible:")), max_output_tokens=patch_output_tokens())
|
||||
metadata = dict(metadata)
|
||||
metadata["repair_model"] = candidate
|
||||
last_metadata = metadata
|
||||
if not ok:
|
||||
last_reason = f"goal_patch_repair_failed:{reason}"
|
||||
continue
|
||||
try:
|
||||
validate_write_output(output)
|
||||
except ValueError as error:
|
||||
last_reason = str(error)
|
||||
continue
|
||||
return True, output, metadata, "ok"
|
||||
return False, "", last_metadata, f"goal_patch_repair_invalid:{last_reason}"
|
||||
|
||||
|
||||
def merge_usage(primary: dict, additional: dict) -> dict:
|
||||
@@ -755,10 +764,11 @@ def run(job_path: str) -> int:
|
||||
try:
|
||||
validate_write_output(safe_local)
|
||||
except ValueError as first_error:
|
||||
repair_model = patch_repair_models(local_model)[0] if patch_repair_models(local_model) else local_model
|
||||
repair_candidates = patch_repair_models(local_model)[:patch_repair_attempts()]
|
||||
repair_model = repair_candidates[0] if repair_candidates else local_model
|
||||
repair_provider = provider_for_model(repair_model)
|
||||
stage(job_path, "local-worker", "running", "Repairing invalid patch output contract", repair_provider, repair_model)
|
||||
emit(goal_id, "H2-tool", "running", "Worker is repairing patch output contract", {"reason": str(first_error), "max_attempts": patch_repair_attempts(), "repair_provider": repair_provider, "repair_model": repair_model})
|
||||
emit(goal_id, "H2-tool", "running", "Worker is repairing patch output contract", {"reason": str(first_error), "max_attempts": patch_repair_attempts(), "repair_provider": repair_provider, "repair_model": repair_model, "repair_candidates": repair_candidates})
|
||||
repaired, repaired_output, repaired_meta, repair_reason = repair_write_output(local_model, local_prompt, safe_local, str(first_error))
|
||||
local_meta = merge_usage(local_meta, repaired_meta)
|
||||
if not repaired:
|
||||
|
||||
Reference in New Issue
Block a user