Skip to content

Commit 2386d73

Browse files
JihaoXinclaude
andcommitted
Title lifecycle: empty at creation, auto-generated after deep research
Creation: - Title stays empty if user doesn't provide one - Dashboard shows "⏰ Pending: ARK will decide later" for empty titles Deep research: - If title is empty, query uses only idea + venue (no placeholder title) - If title is provided, includes it in query as before Title generation (NEW): - After deep research completes, planner generates a proper academic title from idea + venue + deep research context - Written to config.yaml, syncs to DB via dashboard's title auto-sync Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7ab507d commit 2386d73

File tree

3 files changed

+56
-15
lines changed

3 files changed

+56
-15
lines changed

ark/deep_research.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,9 @@ def build_research_query(config: dict) -> str:
7373
goal_anchor = config.get("goal_anchor", "")
7474
research_idea = config.get("research_idea", "") or config.get("idea", "")
7575

76-
# Skip temporary/placeholder titles
77-
is_real_title = title and not title.endswith("...") and title not in ("Untitled Project", "Pending Deep Research")
78-
7976
query_parts = []
8077

81-
if is_real_title:
78+
if title:
8279
query_parts.append(
8380
f"I am writing an academic paper titled \"{title}\" "
8481
f"targeting {venue} conference."

ark/pipeline.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,13 +686,64 @@ def _run_research_phase(self):
686686

687687
self.log("", "RAW")
688688

689+
# Step 1.5: Auto-generate paper title if not provided
690+
self._generate_title_if_needed()
691+
689692
# Step 2: Extract citations from Deep Research report
690693
self._bootstrap_citations_from_deep_research()
691694

692695
self.log_section("Research Phase Complete")
693696

694697
# ==================== Citation Bootstrapping ====================
695698

699+
def _generate_title_if_needed(self):
700+
"""Auto-generate paper title from idea + venue + deep research if not provided."""
701+
title = self.config.get("title", "")
702+
if title:
703+
return # User provided a title, keep it
704+
705+
idea = self.config.get("idea", "")
706+
venue = self.config.get("venue", "")
707+
if not idea:
708+
return
709+
710+
# Read deep research summary for context
711+
dr_file = self.state_dir / "deep_research.md"
712+
dr_summary = ""
713+
if dr_file.exists():
714+
dr_summary = dr_file.read_text()[:2000]
715+
716+
self.log_step("Generating paper title...", "progress")
717+
result = self.run_agent("planner", f"""Generate a concise, academic paper title for the following research.
718+
719+
## Research Idea
720+
{idea[:2000]}
721+
722+
## Target Venue
723+
{venue}
724+
725+
## Background Research (if available)
726+
{dr_summary}
727+
728+
Output ONLY the title — one line, no quotes, no explanation. The title should be:
729+
- Concise (8-15 words)
730+
- Descriptive of the main contribution
731+
- In the style of {venue or 'a top-tier ML conference'} papers
732+
""", timeout=120)
733+
734+
if result and result.strip():
735+
new_title = result.strip().strip('"').strip("'").split('\n')[0].strip()
736+
if len(new_title) > 10:
737+
self.config["title"] = new_title
738+
self.log(f"Generated title: {new_title}", "INFO")
739+
# Update config.yaml on disk
740+
import yaml
741+
config_path = self.code_dir / "config.yaml"
742+
if config_path.exists():
743+
cfg = yaml.safe_load(config_path.read_text()) or {}
744+
cfg["title"] = new_title
745+
config_path.write_text(yaml.dump(cfg, default_flow_style=False, allow_unicode=True))
746+
696747
def _bootstrap_citations_from_deep_research(self):
697748
"""Extract paper titles from Deep Research report via LLM, then fetch BibTeX via API.
698749

ark/webapp/routes.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ async def api_list_projects(request: Request, scope: str = "mine"):
727727
paper_title = _read_paper_title(pdir)
728728
if paper_title and paper_title != p.title:
729729
update_project(session, p, title=paper_title, name=paper_title)
730-
display_title = paper_title or p.title
730+
display_title = paper_title or p.title or "\u23f0 Pending: ARK will decide later"
731731
d = {
732732
"id": p.id,
733733
"name": p.name,
@@ -780,16 +780,9 @@ async def api_create_project(
780780
# Generate project ID: full UUID
781781
project_id = str(uuid.uuid4())
782782

783-
# Title: use provided title, or extract from idea as temporary title
784-
if not title and idea:
785-
# Take first ~80 chars of idea, cut at word boundary
786-
snippet = idea[:80].strip()
787-
last_space = snippet.rfind(' ')
788-
if last_space > 40:
789-
snippet = snippet[:last_space]
790-
title = snippet + ("..." if len(idea) > len(snippet) else "")
791-
if not title:
792-
title = "Untitled Project"
783+
# Title: keep as-is. If user didn't provide, it stays empty.
784+
# Dashboard will show "⏰ Pending" for empty titles.
785+
# Title will be auto-generated after deep research.
793786

794787
pdir = _project_dir(settings, user.id, project_id)
795788
pdir.mkdir(parents=True, exist_ok=True)

0 commit comments

Comments
 (0)