fix: complete streamed patch repair responses
This commit is contained in:
@@ -308,9 +308,9 @@ def patch_repair_attempts() -> int:
|
||||
def patch_output_tokens() -> int:
|
||||
"""Keep a multi-hunk patch from being cut at the generic chat limit."""
|
||||
try:
|
||||
configured = int(os.environ.get("CASAN_GOAL_PATCH_MAX_OUTPUT_TOKENS", "6000"))
|
||||
configured = int(os.environ.get("CASAN_GOAL_PATCH_MAX_OUTPUT_TOKENS", "8192"))
|
||||
except ValueError:
|
||||
configured = 6000
|
||||
configured = 8192
|
||||
return min(max(configured, 512), 8192)
|
||||
|
||||
|
||||
@@ -348,12 +348,14 @@ def repair_write_output(model: str, original_prompt: str, invalid_output: str, c
|
||||
"""
|
||||
if patch_repair_attempts() == 0:
|
||||
return False, "", {}, "goal_patch_missing"
|
||||
repair_prompt = (
|
||||
f"Your previous response violated the required write-output contract: {contract_error}. "
|
||||
def repair_prompt_for(previous_output: str, error: str) -> str:
|
||||
return (
|
||||
f"Your previous response violated the required write-output contract: {error}. "
|
||||
"Return ONLY one complete, applicable unified git diff inside a ```diff fence. The first non-empty line inside the fence MUST be `diff --git `. "
|
||||
"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]}"
|
||||
)
|
||||
f"ORIGINAL CONTRACT:\n{original_prompt}\n\nPREVIOUS INVALID RESPONSE:\n{previous_output[:8000]}"
|
||||
)
|
||||
repair_prompt = repair_prompt_for(invalid_output, contract_error)
|
||||
candidates = patch_repair_models(model)[:patch_repair_attempts()]
|
||||
last_metadata, last_reason = {}, "goal_patch_missing"
|
||||
attempts = []
|
||||
@@ -384,6 +386,14 @@ def repair_write_output(model: str, original_prompt: str, invalid_output: str, c
|
||||
"status": "failed",
|
||||
"reason": last_reason,
|
||||
})
|
||||
# Codex often produces a semantically correct but syntactically
|
||||
# incomplete first diff. Give the same stronger direct model one
|
||||
# corrective pass containing its own failed patch and git error
|
||||
# before sending source context to a weaker gateway.
|
||||
if candidate.endswith("-codex") and candidates.count(candidate) == 1:
|
||||
candidates.insert(attempt_number, candidate)
|
||||
del candidates[patch_repair_attempts():]
|
||||
repair_prompt = repair_prompt_for(output, last_reason)
|
||||
continue
|
||||
attempts.append({
|
||||
"attempt": attempt_number,
|
||||
@@ -815,7 +825,12 @@ def run(job_path: str) -> int:
|
||||
emit(goal_id, "H2-tool", "error", "Worker violated patch output contract after repair", {"reason": reason, "repair_provider": provider_for_model(actual_repair_model), "repair_model": actual_repair_model, "repair_attempts": repaired_meta.get("repair_attempts", [])})
|
||||
raise ValueError(reason)
|
||||
stage(job_path, "local-worker", "pass", "Primary solution prepared", job.get("local_provider", ""), local_model)
|
||||
update_job(job_path, local_draft=safe_local, local_usage=local_meta)
|
||||
update_job(
|
||||
job_path,
|
||||
local_draft=safe_local,
|
||||
local_usage=local_meta,
|
||||
patch_repair_attempts=local_meta.get("repair_attempts", []),
|
||||
)
|
||||
emit(goal_id, "H2-tool", "pass", "Local solution prepared", {"provider": job.get("local_provider", ""), "model": local_model, **local_meta})
|
||||
|
||||
stage(job_path, "cloud-reviewer", "running", "Independent reviewer is challenging and improving the local solution", job.get("cloud_provider", ""), cloud_model)
|
||||
|
||||
Reference in New Issue
Block a user