Skip to content

Commit f342af1

Browse files
JihaoXinclaude
andcommitted
Fix restart losing venue template files (.bib/.tex); allow admin concurrent projects
- Re-copy venue template after _clean_project_state in restart handler, since clean only preserves .cls/.sty/.bst but deletes .bib/.tex/subdirs - Allow admin users to bypass active-project limit on create/restart/continue - Pass is_admin flag through _try_submit_or_pending to skip pending queue Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7bfd017 commit f342af1

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

ark/webapp/routes.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -507,13 +507,13 @@ def _write_user_update(project_dir: Path, message: str, source: str = "webapp"):
507507
f.write_text(yaml.dump({"updates": updates}, allow_unicode=True))
508508

509509

510-
def _try_submit_or_pending(project, pdir, session, settings) -> str:
510+
def _try_submit_or_pending(project, pdir, session, settings, is_admin=False) -> str:
511511
from sqlmodel import select as _sel
512512
active = session.exec(
513513
_sel(Project).where(Project.status.in_(["queued", "running"]))
514514
.where(Project.id != project.id)
515515
).all()
516-
if active:
516+
if active and not is_admin:
517517
update_project(session, project, status="pending")
518518
return "pending"
519519
log_dir = pdir / "logs"
@@ -774,7 +774,7 @@ async def api_create_project(
774774
if len(user_projects) >= MAX_PROJECTS_PER_USER:
775775
raise HTTPException(400, f"Max {MAX_PROJECTS_PER_USER} projects per user.")
776776
active = [p for p in user_projects if p.status in ("queued", "running", "pending")]
777-
if active:
777+
if active and not _is_admin(user):
778778
raise HTTPException(400, "You already have an active project. Wait for it to finish.")
779779

780780
# Generate project ID: full UUID
@@ -900,7 +900,7 @@ async def api_create_project(
900900
"slurm_job_id": "",
901901
}, status_code=201)
902902

903-
final_status = _try_submit_or_pending(project, pdir, session, settings)
903+
final_status = _try_submit_or_pending(project, pdir, session, settings, is_admin=_is_admin(user))
904904

905905
send_telegram_notify(
906906
f"🔬 <b>{project.name}</b> submitted ({final_status})\n"
@@ -1011,7 +1011,7 @@ async def api_restart_project(project_id: str, request: Request):
10111011
raise HTTPException(400, "Only stopped, failed, or done projects can be restarted")
10121012
active = [p for p in get_projects_for_user(session, project.user_id)
10131013
if p.status in ("queued", "running", "pending") and p.id != project_id]
1014-
if active:
1014+
if active and not _is_admin(user):
10151015
raise HTTPException(400, "You already have an active project.")
10161016
pdir = _project_dir(settings, project.user_id, project_id)
10171017

@@ -1036,6 +1036,13 @@ async def api_restart_project(project_id: str, request: Request):
10361036
redo_deep_research = body.get("redo_deep_research", False)
10371037
_clean_project_state(pdir, keep_deep_research=not redo_deep_research)
10381038

1039+
# Re-copy venue template (clean removed .bib/.tex template files)
1040+
venue_fmt = body.get("venue_format") or project.venue_format or ""
1041+
if venue_fmt and venue_fmt != "custom":
1042+
paper_dir = pdir / "paper"
1043+
paper_dir.mkdir(parents=True, exist_ok=True)
1044+
copy_venue_template(venue_fmt, paper_dir)
1045+
10391046
# Rewrite config.yaml with updated settings
10401047
model = body.get("model", "claude-sonnet-4-6")
10411048
_write_config_yaml(pdir, project, model=model)
@@ -1049,7 +1056,7 @@ async def api_restart_project(project_id: str, request: Request):
10491056
session.commit()
10501057
session.refresh(project)
10511058

1052-
final_status = _try_submit_or_pending(project, pdir, session, settings)
1059+
final_status = _try_submit_or_pending(project, pdir, session, settings, is_admin=_is_admin(user))
10531060
send_telegram_notify(
10541061
f"🔄 <b>{project.name}</b> restarted ({final_status})",
10551062
bot_token=project.telegram_token,
@@ -1095,7 +1102,7 @@ async def api_continue_project(project_id: str, request: Request):
10951102
raise HTTPException(400, "Only done, stopped, or failed projects can be continued.")
10961103
active = [p for p in get_projects_for_user(session, project.user_id)
10971104
if p.status in ("queued", "running", "pending") and p.id != project_id]
1098-
if active:
1105+
if active and not _is_admin(user):
10991106
raise HTTPException(400, "You already have an active project.")
11001107
new_max = project.max_iterations + additional
11011108
update_project(session, project, max_iterations=new_max)
@@ -1106,7 +1113,7 @@ async def api_continue_project(project_id: str, request: Request):
11061113
if comment:
11071114
_write_user_update(pdir, comment, source="webapp_continue")
11081115
_write_user_instructions(pdir, comment, source="webapp_continue")
1109-
final_status = _try_submit_or_pending(project, pdir, session, settings)
1116+
final_status = _try_submit_or_pending(project, pdir, session, settings, is_admin=_is_admin(user))
11101117
return JSONResponse({"ok": True, "status": final_status, "max_iterations": new_max})
11111118

11121119

0 commit comments

Comments
 (0)