fix(simulation): fix clone 400→404 for not found, remove redundant makedirs, hoist uuid import

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ubuntu 2026-05-03 21:52:35 +00:00
parent a6b4ccca3c
commit a74c0975fe
3 changed files with 11 additions and 5 deletions

View File

@ -2889,6 +2889,8 @@ def clone_simulation(simulation_id: str):
manager = SimulationManager() manager = SimulationManager()
try: try:
new_state = manager.clone_simulation(simulation_id, project_id) new_state = manager.clone_simulation(simulation_id, project_id)
except LookupError as e:
return jsonify({"success": False, "error": str(e)}), 404
except ValueError as e: except ValueError as e:
return jsonify({"success": False, "error": str(e)}), 400 return jsonify({"success": False, "error": str(e)}), 400
@ -2902,4 +2904,4 @@ def clone_simulation(simulation_id: str):
}) })
except Exception as e: except Exception as e:
logger.error(f"clone_simulation failed: {e}") logger.error(f"clone_simulation failed: {e}")
return jsonify({"success": False, "error": str(e)}), 500 return jsonify({"success": False, "error": str(e), "traceback": traceback.format_exc()}), 500

View File

@ -7,6 +7,7 @@ Uses preset scripts with LLM-generated configuration parameters.
import os import os
import json import json
import shutil import shutil
import uuid
from typing import Dict, Any, List, Optional from typing import Dict, Any, List, Optional
from dataclasses import dataclass, field from dataclasses import dataclass, field
from datetime import datetime from datetime import datetime
@ -222,7 +223,6 @@ class SimulationManager:
Returns: Returns:
SimulationState SimulationState
""" """
import uuid
simulation_id = f"sim_{uuid.uuid4().hex[:12]}" simulation_id = f"sim_{uuid.uuid4().hex[:12]}"
state = SimulationState( state = SimulationState(
@ -654,12 +654,11 @@ class SimulationManager:
""" """
source_state = self.get_simulation(source_simulation_id) source_state = self.get_simulation(source_simulation_id)
if not source_state: if not source_state:
raise ValueError(f"Source simulation {source_simulation_id} not found") raise LookupError(f"Source simulation {source_simulation_id} not found")
if source_state.status == SimulationStatus.CREATED: if source_state.status == SimulationStatus.CREATED:
raise ValueError("Cannot clone a simulation in 'created' status (no profiles yet)") raise ValueError("Cannot clone a simulation in 'created' status (no profiles yet)")
import uuid
new_sim_id = f"sim_{uuid.uuid4().hex[:12]}" new_sim_id = f"sim_{uuid.uuid4().hex[:12]}"
new_state = SimulationState( new_state = SimulationState(
simulation_id=new_sim_id, simulation_id=new_sim_id,
@ -677,7 +676,6 @@ class SimulationManager:
src_dir = self._get_simulation_dir(source_simulation_id) src_dir = self._get_simulation_dir(source_simulation_id)
dst_dir = self._get_simulation_dir(new_sim_id) dst_dir = self._get_simulation_dir(new_sim_id)
os.makedirs(dst_dir, exist_ok=True)
for fname in ("reddit_profiles.json", "twitter_profiles.csv", "agent_profiles.json"): for fname in ("reddit_profiles.json", "twitter_profiles.csv", "agent_profiles.json"):
src_file = os.path.join(src_dir, fname) src_file = os.path.join(src_dir, fname)

View File

@ -88,3 +88,9 @@ def test_clone_status_is_profiles_ready(completed_sim):
state = json.loads(state_file.read_text()) state = json.loads(state_file.read_text())
assert state["status"] == "profiles_ready" assert state["status"] == "profiles_ready"
assert state["parent_simulation_id"] == src_id assert state["parent_simulation_id"] == src_id
def test_clone_source_not_found_returns_404(app_client):
client, tmp_path = app_client
resp = client.post("/api/simulation/nonexistent_sim/clone", json={"project_id": "proj_x"})
assert resp.status_code == 404