Minimal working example: - If OPENAI_API_KEY is set and the OpenAI SDK is available, ask the model for a unified diff. - Otherwise, return a tiny, valid unified diff against the first relevant file (demo fallback).
(fail_log: str, relevant_files: dict)
| 15 | |
| 16 | |
| 17 | def model_call_patch(fail_log: str, relevant_files: dict) -> str: |
| 18 | """ |
| 19 | Minimal working example: |
| 20 | - If OPENAI_API_KEY is set and the OpenAI SDK is available, ask the model for a unified diff. |
| 21 | - Otherwise, return a tiny, valid unified diff against the first relevant file (demo fallback). |
| 22 | """ |
| 23 | |
| 24 | # 1) Try LLM-backed patch generation (only if configured) |
| 25 | if OpenAI and os.getenv("OPENAI_API_KEY"): |
| 26 | client = OpenAI() |
| 27 | model = os.getenv("PATCH_MODEL", "gpt-4o-mini") |
| 28 | |
| 29 | sys_msg = ( |
| 30 | "You are a code repair assistant. Output ONLY a unified diff patch that " |
| 31 | "can be applied with `git apply -p0`. Do NOT include any explanations." |
| 32 | ) |
| 33 | files_blob = "\n\n".join( |
| 34 | f"{path}:\n{content}" for path, content in relevant_files.items() |
| 35 | ) |
| 36 | user_msg = ( |
| 37 | "Given the failing test log and the repository files, produce a minimal fix:\n\n" |
| 38 | f"Failing test log:\n{fail_log}\n\n" |
| 39 | f"Relevant files (path => content):\n{files_blob}\n" |
| 40 | ) |
| 41 | |
| 42 | resp = client.chat.completions.create( |
| 43 | model=model, |
| 44 | temperature=0, |
| 45 | messages=[ |
| 46 | {"role": "system", "content": sys_msg}, |
| 47 | {"role": "user", "content": user_msg}, |
| 48 | ], |
| 49 | ) |
| 50 | if not resp.choices or resp.choices[0].message is None: |
| 51 | raise ValueError("LLM returned empty or filtered response") |
| 52 | patch = resp.choices[0].message.content.strip() |
| 53 | return patch |
| 54 | |
| 55 | # 2) Fallback: return a harmless, valid unified diff so the example runs without any API keys |
| 56 | if not relevant_files: |
| 57 | demo_path = "README.md" |
| 58 | old = "" |
| 59 | else: |
| 60 | demo_path = next(iter(relevant_files.keys())) |
| 61 | old = relevant_files[demo_path] |
| 62 | |
| 63 | # Minimal unified diff; uses -p0 friendly paths (a/ and b/) |
| 64 | fallback_patch = dedent(f"""\ |
| 65 | --- a/{demo_path} |
| 66 | +++ b/{demo_path} |
| 67 | @@ |
| 68 | {old or ""} |
| 69 | +# patched-by-demo |
| 70 | """) |
| 71 | return fallback_patch |
| 72 | |
| 73 | |
| 74 | def run_task_local( |
no test coverage detected
searching dependent graphs…