Skip to content

Commit 69f2270

Browse files
committed
Refactor MCP endpoints to remove '/mcp' prefix and improve response handling
1 parent 8a38160 commit 69f2270

File tree

1 file changed

+61
-40
lines changed

1 file changed

+61
-40
lines changed

app/main.py

Lines changed: 61 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,17 @@ async def get_project_status(project_id: str):
103103

104104
return ProjectResponse(**status)
105105

106-
@app.post("/mcp/compile")
107-
async def mcp_compile_rust(request: dict):
106+
@app.post("/compile") # Changed from /mcp/compile
107+
async def compile_rust(request: dict):
108108
"""MCP endpoint to compile Rust code"""
109109
if "code" not in request:
110110
raise HTTPException(status_code=400, detail="Missing 'code' field")
111111

112112
return rust_mcp.compile_rust_code(request["code"])
113113

114-
@app.post("/mcp/compile-and-fix")
115-
async def mcp_compile_and_fix_rust(request: dict):
116-
"""MCP endpoint to compile and fix Rust code"""
114+
@app.post("/compile-and-fix") # Changed from /mcp/compile-and-fix
115+
async def compile_and_fix_rust(request: dict):
116+
"""Endpoint to compile and fix Rust code"""
117117
if "code" not in request or "description" not in request:
118118
raise HTTPException(status_code=400, detail="Missing required fields")
119119

@@ -125,18 +125,19 @@ async def mcp_compile_and_fix_rust(request: dict):
125125
max_attempts=max_attempts
126126
)
127127

128-
# If successful, return raw source code
128+
# Format as text with filename markers
129+
output_text = ""
130+
for filename, content in result["final_files"].items():
131+
output_text += f"[filename: {filename}]\n{content}\n\n"
132+
133+
# For successful fixes, return a text response with the combined code
129134
if result["success"]:
130-
# Format as raw text with filename markers
131-
output_text = ""
132-
for filename, content in result["final_files"].items():
133-
output_text += f"[filename: {filename}]\n{content}\n\n"
134-
135-
# Return as plain text
136135
return PlainTextResponse(content=output_text.strip())
137136
else:
138-
# For errors, we can still return JSON
139-
return result
137+
# For errors, return the JSON with detailed error information
138+
# Add the combined text to the response for easier client use
139+
result["combined_text"] = output_text.strip()
140+
return JSONResponse(content=result)
140141

141142
async def handle_project_generation(
142143
project_id: str,
@@ -415,6 +416,7 @@ async def generate_project_sync(request: ProjectRequest):
415416

416417
# Ensure essential files exist
417418
if "Cargo.toml" not in files:
419+
# Create a basic Cargo.toml if it's missing
418420
project_name = request.description.lower().replace(" ", "_").replace("-", "_")[:20]
419421
files["Cargo.toml"] = f"""[package]
420422
name = "{project_name}"
@@ -425,30 +427,49 @@ async def generate_project_sync(request: ProjectRequest):
425427
"""
426428

427429
if "src/main.rs" not in files and "src\\main.rs" not in files:
430+
# Create a basic main.rs if it's missing
428431
files["src/main.rs"] = """fn main() {
429432
println!("Hello, world!");
430433
}
431434
"""
432435

433-
# Write files
434-
parser.write_files(files, temp_dir)
436+
file_paths = parser.write_files(files, temp_dir)
437+
438+
status.update({
439+
"status": "compiling",
440+
"message": "Compiling project",
441+
"files": file_paths
442+
})
443+
save_status(temp_dir, status)
435444

436445
# Compile the project
437446
success, output = compiler.build_project(temp_dir)
438447

439448
if not success:
440-
# Try to fix compilation errors
449+
# Project failed to compile, try to fix errors
450+
status.update({
451+
"status": "error",
452+
"message": "Compilation failed, attempting to fix",
453+
"build_output": output
454+
})
455+
save_status(temp_dir, status)
456+
457+
# Extract error context
441458
error_context = compiler.extract_error_context(output)
442459

443460
# Skip vector search if environment variable is set
461+
skip_vector_search = os.getenv("SKIP_VECTOR_SEARCH", "").lower() == "true"
444462
similar_errors = []
463+
445464
if not skip_vector_search:
446465
try:
466+
# Find similar errors in vector DB
447467
error_embedding = llm_client.get_embeddings([error_context["full_error"]])[0]
448468
similar_errors = vector_store.search("error_examples", error_embedding, limit=3)
449469
except Exception as e:
450470
print(f"Vector search error (non-critical): {e}")
451-
471+
# Continue without vector search results
472+
452473
# Generate fix prompt
453474
fix_examples = ""
454475
if similar_errors:
@@ -468,41 +489,41 @@ async def generate_project_sync(request: ProjectRequest):
468489
469490
Please provide the fixed code for all affected files.
470491
"""
471-
492+
472493
# Get fix from LLM
473494
fix_response = llm_client.generate_text(fix_prompt)
474495

475496
# Parse and apply fixes
476497
fixed_files = parser.parse_response(fix_response)
477498
for filename, content in fixed_files.items():
478-
files[filename] = content # Update our files dictionary
479499
file_path = os.path.join(temp_dir, filename)
480-
os.makedirs(os.path.dirname(file_path), exist_ok=True)
481500
with open(file_path, 'w') as f:
482501
f.write(content)
483502

484503
# Try compiling again
485504
success, output = compiler.build_project(temp_dir)
486505

487-
# Format as raw text with filename markers
488-
output_text = ""
489-
for filename, content in files.items():
490-
output_text += f"[filename: {filename}]\n{content}\n\n"
491-
492-
# Include build result as a comment
493-
build_status = "# Build succeeded" if success else f"# Build failed\n# {output}"
494-
output_text += f"{build_status}\n"
506+
if success:
507+
# Project compiled successfully, try running it
508+
run_success, run_output = compiler.run_project(temp_dir)
509+
510+
status.update({
511+
"status": "completed",
512+
"message": "Project generated successfully",
513+
"build_output": output,
514+
"run_output": run_output if run_success else "Failed to run project"
515+
})
516+
else:
517+
status.update({
518+
"status": "failed",
519+
"message": "Failed to generate working project",
520+
"build_output": output
521+
})
495522

496-
# Return as plain text
497-
return PlainTextResponse(content=output_text.strip())
523+
save_status(temp_dir, status)
498524

525+
# Return all files as text
526+
all_files_content = "\n".join([f"[filename: {f}]\n{open(os.path.join(temp_dir, f)).read()}\n" for f in file_paths])
527+
return PlainTextResponse(content=all_files_content)
499528
except Exception as e:
500-
# Return error message
501-
return JSONResponse(
502-
status_code=500,
503-
content={"error": f"Project generation failed: {str(e)}"}
504-
)
505-
506-
if __name__ == "__main__":
507-
import uvicorn
508-
uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=True)
529+
raise HTTPException(status_code=500, detail=f"Error generating project: {str(e)}")

0 commit comments

Comments
 (0)