feat: implement session-based architecture for OPRO
- Add session layer above runs to group related optimization tasks - Sessions use first task description as name instead of 'Session 1' - Simplified sidebar: show sessions without expansion - Add '+ 新建任务' button in header to create runs within session - Fix: reload sessions after creating new run - Add debugging logs for candidate generation - Backend: auto-update session name with first task description
This commit is contained in:
@@ -66,10 +66,57 @@ def set_session_model(sid: str, model_name: str | None):
|
||||
# TRUE OPRO SESSION MANAGEMENT
|
||||
# ============================================================================
|
||||
|
||||
# Session storage (contains multiple runs)
|
||||
OPRO_SESSIONS = {}
|
||||
|
||||
def create_opro_session(session_name: str = None) -> str:
|
||||
"""
|
||||
Create a new OPRO session that can contain multiple runs.
|
||||
|
||||
Args:
|
||||
session_name: Optional name for the session
|
||||
|
||||
Returns:
|
||||
session_id: Unique identifier for this session
|
||||
"""
|
||||
session_id = uuid.uuid4().hex
|
||||
OPRO_SESSIONS[session_id] = {
|
||||
"session_name": session_name or "新会话", # Will be updated with first task description
|
||||
"created_at": uuid.uuid1().time,
|
||||
"run_ids": [], # List of run IDs in this session
|
||||
"chat_history": [] # Cross-run chat history
|
||||
}
|
||||
return session_id
|
||||
|
||||
|
||||
def get_opro_session(session_id: str) -> Dict[str, Any]:
|
||||
"""Get OPRO session by ID."""
|
||||
return OPRO_SESSIONS.get(session_id)
|
||||
|
||||
|
||||
def list_opro_sessions() -> List[Dict[str, Any]]:
|
||||
"""
|
||||
List all OPRO sessions with summary information.
|
||||
|
||||
Returns:
|
||||
List of session summaries
|
||||
"""
|
||||
return [
|
||||
{
|
||||
"session_id": session_id,
|
||||
"session_name": session["session_name"],
|
||||
"num_runs": len(session["run_ids"]),
|
||||
"created_at": session["created_at"]
|
||||
}
|
||||
for session_id, session in OPRO_SESSIONS.items()
|
||||
]
|
||||
|
||||
|
||||
def create_opro_run(
|
||||
task_description: str,
|
||||
test_cases: List[Tuple[str, str]] = None,
|
||||
model_name: str = None
|
||||
model_name: str = None,
|
||||
session_id: str = None
|
||||
) -> str:
|
||||
"""
|
||||
Create a new OPRO optimization run.
|
||||
@@ -78,6 +125,7 @@ def create_opro_run(
|
||||
task_description: Description of the task to optimize for
|
||||
test_cases: List of (input, expected_output) tuples for evaluation
|
||||
model_name: Optional model name to use
|
||||
session_id: Optional session ID to associate this run with
|
||||
|
||||
Returns:
|
||||
run_id: Unique identifier for this OPRO run
|
||||
@@ -87,6 +135,7 @@ def create_opro_run(
|
||||
"task_description": task_description,
|
||||
"test_cases": test_cases or [],
|
||||
"model_name": model_name,
|
||||
"session_id": session_id, # Link to parent session
|
||||
"iteration": 0,
|
||||
"trajectory": [], # List of (instruction, score) tuples
|
||||
"best_instruction": None,
|
||||
@@ -95,6 +144,14 @@ def create_opro_run(
|
||||
"created_at": uuid.uuid1().time,
|
||||
"status": "active" # active, completed, failed
|
||||
}
|
||||
|
||||
# Add run to session if session_id provided
|
||||
if session_id and session_id in OPRO_SESSIONS:
|
||||
OPRO_SESSIONS[session_id]["run_ids"].append(run_id)
|
||||
# Update session name with first task description if it's still default
|
||||
if OPRO_SESSIONS[session_id]["session_name"] == "新会话" and len(OPRO_SESSIONS[session_id]["run_ids"]) == 1:
|
||||
OPRO_SESSIONS[session_id]["session_name"] = task_description
|
||||
|
||||
return run_id
|
||||
|
||||
|
||||
@@ -206,13 +263,22 @@ def complete_opro_run(run_id: str):
|
||||
run["status"] = "completed"
|
||||
|
||||
|
||||
def list_opro_runs() -> List[Dict[str, Any]]:
|
||||
def list_opro_runs(session_id: str = None) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
List all OPRO runs with summary information.
|
||||
|
||||
Args:
|
||||
session_id: Optional session ID to filter runs by session
|
||||
|
||||
Returns:
|
||||
List of run summaries
|
||||
"""
|
||||
runs_to_list = OPRO_RUNS.items()
|
||||
|
||||
# Filter by session if provided
|
||||
if session_id:
|
||||
runs_to_list = [(rid, r) for rid, r in runs_to_list if r.get("session_id") == session_id]
|
||||
|
||||
return [
|
||||
{
|
||||
"run_id": run_id,
|
||||
@@ -220,7 +286,8 @@ def list_opro_runs() -> List[Dict[str, Any]]:
|
||||
"iteration": run["iteration"],
|
||||
"best_score": run["best_score"],
|
||||
"num_test_cases": len(run["test_cases"]),
|
||||
"status": run["status"]
|
||||
"status": run["status"],
|
||||
"session_id": run.get("session_id")
|
||||
}
|
||||
for run_id, run in OPRO_RUNS.items()
|
||||
for run_id, run in runs_to_list
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user