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:
2025-12-06 21:26:24 +08:00
parent 1376d60ed5
commit da30a0999c
4 changed files with 380 additions and 42 deletions

View File

@@ -14,6 +14,7 @@ from .opro.session_state import USER_FEEDBACK_LOG
# True OPRO session management
from .opro.session_state import (
create_opro_session, get_opro_session, list_opro_sessions,
create_opro_run, get_opro_run, update_opro_iteration,
add_opro_evaluation, get_opro_trajectory, set_opro_test_cases,
complete_opro_run, list_opro_runs
@@ -122,6 +123,7 @@ class CreateOPRORunReq(BaseModel):
task_description: str
test_cases: Optional[List[TestCase]] = None
model_name: Optional[str] = None
session_id: Optional[str] = None # Optional session to associate with
class OPROIterateReq(BaseModel):
@@ -360,12 +362,62 @@ def set_model(req: SetModelReq):
# TRUE OPRO ENDPOINTS (System Instruction Optimization)
# ============================================================================
# Session Management
@app.post("/opro/session/create", tags=["opro-true"])
def opro_create_session(session_name: str = None):
"""
Create a new OPRO session that can contain multiple runs.
"""
session_id = create_opro_session(session_name=session_name)
session = get_opro_session(session_id)
return ok({
"session_id": session_id,
"session_name": session["session_name"],
"num_runs": len(session["run_ids"])
})
@app.get("/opro/sessions", tags=["opro-true"])
def opro_list_sessions():
"""
List all OPRO sessions.
"""
sessions = list_opro_sessions()
return ok({"sessions": sessions})
@app.get("/opro/session/{session_id}", tags=["opro-true"])
def opro_get_session(session_id: str):
"""
Get detailed information about an OPRO session.
"""
session = get_opro_session(session_id)
if not session:
raise AppException(404, "Session not found", "SESSION_NOT_FOUND")
# Get all runs in this session
runs = list_opro_runs(session_id=session_id)
return ok({
"session_id": session_id,
"session_name": session["session_name"],
"created_at": session["created_at"],
"num_runs": len(session["run_ids"]),
"runs": runs
})
# Run Management
@app.post("/opro/create", tags=["opro-true"])
def opro_create_run(req: CreateOPRORunReq):
"""
Create a new OPRO optimization run.
This starts a new system instruction optimization process for a given task.
Optionally can be associated with a session.
"""
# Convert test cases from Pydantic models to tuples
test_cases = None
@@ -375,7 +427,8 @@ def opro_create_run(req: CreateOPRORunReq):
run_id = create_opro_run(
task_description=req.task_description,
test_cases=test_cases,
model_name=req.model_name
model_name=req.model_name,
session_id=req.session_id
)
run = get_opro_run(run_id)
@@ -385,7 +438,8 @@ def opro_create_run(req: CreateOPRORunReq):
"task_description": run["task_description"],
"num_test_cases": len(run["test_cases"]),
"iteration": run["iteration"],
"status": run["status"]
"status": run["status"],
"session_id": run.get("session_id")
})