Spaces:
Sleeping
Sleeping
Deploy code agent from GitHub Actions
Browse files
app.py
CHANGED
|
@@ -22,6 +22,8 @@ class CodeRepairRequest(BaseModel):
|
|
| 22 |
repair_summary: str | None = None
|
| 23 |
failure_type: str | None = None
|
| 24 |
help_message: str | None = None
|
|
|
|
|
|
|
| 25 |
|
| 26 |
|
| 27 |
@app.get("/")
|
|
@@ -49,6 +51,95 @@ def load_model():
|
|
| 49 |
return tokenizer, model
|
| 50 |
|
| 51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
def get_environment_guidance(request: CodeRepairRequest):
|
| 53 |
if request.failure_type == "MAVEN_NOT_AVAILABLE":
|
| 54 |
summary = (
|
|
@@ -130,6 +221,12 @@ Project type:
|
|
| 130 |
File path:
|
| 131 |
{file_path}
|
| 132 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
Failure type:
|
| 134 |
{failure_type}
|
| 135 |
|
|
@@ -154,6 +251,8 @@ Return only these sections:
|
|
| 154 |
3. Suggested code change
|
| 155 |
4. Verification step
|
| 156 |
|
|
|
|
|
|
|
| 157 |
If the failure is Maven not available or Maven Wrapper missing, clearly say no application source code change is required.
|
| 158 |
Do not include system/user/assistant labels.
|
| 159 |
Do not repeat the prompt.
|
|
@@ -211,6 +310,11 @@ def fallback_code_guidance(request: CodeRepairRequest):
|
|
| 211 |
if environment_guidance:
|
| 212 |
return environment_guidance
|
| 213 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
if request.error_log:
|
| 215 |
summary = (
|
| 216 |
"A code-level issue may exist based on the provided error log. "
|
|
@@ -271,7 +375,7 @@ def remove_prompt_leak(text: str):
|
|
| 271 |
return cleaned.strip()
|
| 272 |
|
| 273 |
|
| 274 |
-
def clean_output(text: str):
|
| 275 |
cleaned = remove_prompt_leak(text)
|
| 276 |
if not cleaned:
|
| 277 |
return None
|
|
@@ -298,6 +402,18 @@ def clean_output(text: str):
|
|
| 298 |
if any(pattern.lower() in cleaned.lower() for pattern in bad_patterns):
|
| 299 |
return None
|
| 300 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 301 |
return cleaned
|
| 302 |
|
| 303 |
|
|
@@ -308,12 +424,17 @@ def suggest_code_fix(request: CodeRepairRequest):
|
|
| 308 |
if environment_guidance:
|
| 309 |
return environment_guidance
|
| 310 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 311 |
fallback_result = fallback_code_guidance(request)
|
| 312 |
|
| 313 |
try:
|
| 314 |
prompt = build_prompt(request)
|
| 315 |
llm_text = call_llm(prompt)
|
| 316 |
-
cleaned_text = clean_output(llm_text)
|
| 317 |
|
| 318 |
if not cleaned_text:
|
| 319 |
return fallback_result
|
|
|
|
| 22 |
repair_summary: str | None = None
|
| 23 |
failure_type: str | None = None
|
| 24 |
help_message: str | None = None
|
| 25 |
+
success: bool | None = None
|
| 26 |
+
exit_code: int | None = None
|
| 27 |
|
| 28 |
|
| 29 |
@app.get("/")
|
|
|
|
| 51 |
return tokenizer, model
|
| 52 |
|
| 53 |
|
| 54 |
+
def combined_context(request: CodeRepairRequest):
|
| 55 |
+
return f"""
|
| 56 |
+
{request.error_log or ""}
|
| 57 |
+
{request.root_cause or ""}
|
| 58 |
+
{request.repair_summary or ""}
|
| 59 |
+
{request.code_snippet or ""}
|
| 60 |
+
""".lower()
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def has_mockito_warning(request: CodeRepairRequest):
|
| 64 |
+
context = combined_context(request)
|
| 65 |
+
|
| 66 |
+
return (
|
| 67 |
+
"mockito" in context
|
| 68 |
+
and (
|
| 69 |
+
"dynamic loading of agents" in context
|
| 70 |
+
or "dynamic java agent" in context
|
| 71 |
+
or "self-attaching" in context
|
| 72 |
+
or "java agent" in context
|
| 73 |
+
)
|
| 74 |
+
)
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def is_successful_execution(request: CodeRepairRequest):
|
| 78 |
+
context = combined_context(request)
|
| 79 |
+
|
| 80 |
+
if request.success is True:
|
| 81 |
+
return True
|
| 82 |
+
|
| 83 |
+
if request.exit_code == 0:
|
| 84 |
+
return True
|
| 85 |
+
|
| 86 |
+
if "passed the current qa execution" in context:
|
| 87 |
+
return True
|
| 88 |
+
|
| 89 |
+
if "build completed successfully" in context:
|
| 90 |
+
return True
|
| 91 |
+
|
| 92 |
+
if "tests run:" in context and "failures: 0" in context and "errors: 0" in context:
|
| 93 |
+
return True
|
| 94 |
+
|
| 95 |
+
if "no blocking runtime error detected" in context:
|
| 96 |
+
return True
|
| 97 |
+
|
| 98 |
+
return False
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
def get_successful_execution_guidance(request: CodeRepairRequest):
|
| 102 |
+
if not is_successful_execution(request):
|
| 103 |
+
return None
|
| 104 |
+
|
| 105 |
+
if has_mockito_warning(request):
|
| 106 |
+
summary = (
|
| 107 |
+
"Problem: The project build and tests passed successfully, but a Mockito dynamic Java agent loading warning was detected.\n\n"
|
| 108 |
+
"Safe fix approach: This is not a blocking application code failure. Do not change Java source files just because of this warning. "
|
| 109 |
+
"Review the Maven test configuration and prepare a future-safe Mockito Java agent setup for newer JDK compatibility.\n\n"
|
| 110 |
+
"Suggested code change: No application source code change is required. If you want to remove the warning, update the Maven test configuration "
|
| 111 |
+
"to load Mockito as a Java agent according to Mockito documentation.\n\n"
|
| 112 |
+
"Verification step: Rerun the Maven test command and confirm tests still pass with zero failures and zero errors."
|
| 113 |
+
)
|
| 114 |
+
|
| 115 |
+
return {
|
| 116 |
+
"agent": "code-agent",
|
| 117 |
+
"mode": "rule-based",
|
| 118 |
+
"summary": summary,
|
| 119 |
+
"risk_level": "LOW",
|
| 120 |
+
"auto_apply": False,
|
| 121 |
+
"suggested_patch": None,
|
| 122 |
+
"verification": "No source-code fix is required. Review Maven test configuration only if you want to address the Mockito warning."
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
summary = (
|
| 126 |
+
"Problem: No blocking code-level failure was detected.\n\n"
|
| 127 |
+
"Safe fix approach: The project build and tests passed successfully. No repair should be applied to application source files.\n\n"
|
| 128 |
+
"Suggested code change: No code change is required.\n\n"
|
| 129 |
+
"Verification step: Keep the current passing state and rerun Stitch QA after future changes."
|
| 130 |
+
)
|
| 131 |
+
|
| 132 |
+
return {
|
| 133 |
+
"agent": "code-agent",
|
| 134 |
+
"mode": "rule-based",
|
| 135 |
+
"summary": summary,
|
| 136 |
+
"risk_level": "LOW",
|
| 137 |
+
"auto_apply": False,
|
| 138 |
+
"suggested_patch": None,
|
| 139 |
+
"verification": "No code fix is required because the current execution passed."
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
|
| 143 |
def get_environment_guidance(request: CodeRepairRequest):
|
| 144 |
if request.failure_type == "MAVEN_NOT_AVAILABLE":
|
| 145 |
summary = (
|
|
|
|
| 221 |
File path:
|
| 222 |
{file_path}
|
| 223 |
|
| 224 |
+
Execution success:
|
| 225 |
+
{request.success}
|
| 226 |
+
|
| 227 |
+
Exit code:
|
| 228 |
+
{request.exit_code}
|
| 229 |
+
|
| 230 |
Failure type:
|
| 231 |
{failure_type}
|
| 232 |
|
|
|
|
| 251 |
3. Suggested code change
|
| 252 |
4. Verification step
|
| 253 |
|
| 254 |
+
If execution success is true or exit code is 0, do not say the project failed.
|
| 255 |
+
If tests passed and only warnings exist, say no blocking application source code change is required.
|
| 256 |
If the failure is Maven not available or Maven Wrapper missing, clearly say no application source code change is required.
|
| 257 |
Do not include system/user/assistant labels.
|
| 258 |
Do not repeat the prompt.
|
|
|
|
| 310 |
if environment_guidance:
|
| 311 |
return environment_guidance
|
| 312 |
|
| 313 |
+
successful_guidance = get_successful_execution_guidance(request)
|
| 314 |
+
|
| 315 |
+
if successful_guidance:
|
| 316 |
+
return successful_guidance
|
| 317 |
+
|
| 318 |
if request.error_log:
|
| 319 |
summary = (
|
| 320 |
"A code-level issue may exist based on the provided error log. "
|
|
|
|
| 375 |
return cleaned.strip()
|
| 376 |
|
| 377 |
|
| 378 |
+
def clean_output(text: str, request: CodeRepairRequest):
|
| 379 |
cleaned = remove_prompt_leak(text)
|
| 380 |
if not cleaned:
|
| 381 |
return None
|
|
|
|
| 402 |
if any(pattern.lower() in cleaned.lower() for pattern in bad_patterns):
|
| 403 |
return None
|
| 404 |
|
| 405 |
+
if is_successful_execution(request):
|
| 406 |
+
incorrect_failure_phrases = [
|
| 407 |
+
"failed to pass",
|
| 408 |
+
"project failed",
|
| 409 |
+
"build failed",
|
| 410 |
+
"tests failed",
|
| 411 |
+
"failed during qa execution"
|
| 412 |
+
]
|
| 413 |
+
|
| 414 |
+
if any(phrase in cleaned.lower() for phrase in incorrect_failure_phrases):
|
| 415 |
+
return None
|
| 416 |
+
|
| 417 |
return cleaned
|
| 418 |
|
| 419 |
|
|
|
|
| 424 |
if environment_guidance:
|
| 425 |
return environment_guidance
|
| 426 |
|
| 427 |
+
successful_guidance = get_successful_execution_guidance(request)
|
| 428 |
+
|
| 429 |
+
if successful_guidance:
|
| 430 |
+
return successful_guidance
|
| 431 |
+
|
| 432 |
fallback_result = fallback_code_guidance(request)
|
| 433 |
|
| 434 |
try:
|
| 435 |
prompt = build_prompt(request)
|
| 436 |
llm_text = call_llm(prompt)
|
| 437 |
+
cleaned_text = clean_output(llm_text, request)
|
| 438 |
|
| 439 |
if not cleaned_text:
|
| 440 |
return fallback_result
|