MukulRay commited on
Commit
ad651e3
·
1 Parent(s): b98fd6c

Phase 2.2-2.3: add doi to Paper, populate from S2 externalIds, integrate OpenAlex into retriever

Browse files
src/agents/retriever.py CHANGED
@@ -7,6 +7,7 @@ from src.retriever_utils import (
7
  search_semantic_scholar,
8
  search_web,
9
  build_citation_graph,
 
10
  )
11
 
12
  load_dotenv()
@@ -95,6 +96,51 @@ def retriever_node(state: ResearchState) -> ResearchState:
95
  if i < len(sub_questions) - 1:
96
  time.sleep(1)
97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  # Sort papers by hybrid score descending
99
  all_papers.sort(key=lambda p: p.hybrid_score, reverse=True)
100
 
 
7
  search_semantic_scholar,
8
  search_web,
9
  build_citation_graph,
10
+ hybrid_score,
11
  )
12
 
13
  load_dotenv()
 
96
  if i < len(sub_questions) - 1:
97
  time.sleep(1)
98
 
99
+ # --- Phase 2.2: OpenAlex augmentation ---
100
+ from src.openalex_utils import search_openalex
101
+ existing_dois = {p.doi.lower() for p in all_papers if p.doi}
102
+ existing_ids = {p.paper_id for p in all_papers}
103
+
104
+ if len(all_papers) < 12:
105
+ for question in sub_questions[:2]: # only first 2 sub-questions
106
+ try:
107
+ oa_results = search_openalex(question, max_results=3)
108
+ for r in oa_results:
109
+ doi_lower = (r.get("doi") or "").lower()
110
+ pid = r.get("paper_id") or ""
111
+ # Skip if we already have this paper by DOI or paper_id
112
+ if doi_lower and doi_lower in existing_dois:
113
+ continue
114
+ if pid in existing_ids:
115
+ continue
116
+ # Build Paper object from OpenAlex result
117
+ p = Paper(
118
+ title=r.get("title") or "",
119
+ abstract=r.get("abstract") or "",
120
+ year=r.get("year") or 0,
121
+ citation_count=r.get("citation_count") or 0,
122
+ paper_id=pid,
123
+ authors=[a.strip() for a in (r.get("authors") or "").split(",") if a.strip()],
124
+ references=[],
125
+ doi=r.get("doi") or "",
126
+ source="openalex",
127
+ )
128
+ if not p.title or not p.year:
129
+ continue
130
+ p.hybrid_score = hybrid_score(
131
+ semantic_sim=0.3, # conservative default — no query embedding for OA papers
132
+ year=p.year,
133
+ citation_count=p.citation_count,
134
+ decay_config=decay_config,
135
+ )
136
+ all_papers.append(p)
137
+ existing_dois.add(doi_lower)
138
+ existing_ids.add(pid)
139
+ time.sleep(0.5) # be polite to OpenAlex
140
+ except Exception as e:
141
+ logger.warning(f"OpenAlex augmentation failed for '{question[:40]}': {e}")
142
+ continue
143
+
144
  # Sort papers by hybrid score descending
145
  all_papers.sort(key=lambda p: p.hybrid_score, reverse=True)
146
 
src/retriever_utils.py CHANGED
@@ -129,7 +129,7 @@ def search_semantic_scholar(
129
  params = {
130
  "query": query,
131
  "limit": limit,
132
- "fields": "title,abstract,year,citationCount,authors,references,paperId",
133
  }
134
 
135
  time.sleep(3) # rate limit guard
@@ -170,6 +170,7 @@ def search_semantic_scholar(
170
  if ref.get("paperId")
171
  ]
172
 
 
173
  paper = Paper(
174
  title=r.get("title") or "Untitled",
175
  abstract=abstract,
@@ -178,6 +179,7 @@ def search_semantic_scholar(
178
  paper_id=r.get("paperId") or "",
179
  authors=authors,
180
  references=references,
 
181
  hybrid_score=hybrid_score(sim, year, citations, decay_config),
182
  source="semantic_scholar",
183
  )
 
129
  params = {
130
  "query": query,
131
  "limit": limit,
132
+ "fields": "title,abstract,year,citationCount,authors,references,paperId,externalIds",
133
  }
134
 
135
  time.sleep(3) # rate limit guard
 
170
  if ref.get("paperId")
171
  ]
172
 
173
+ doi = (r.get("externalIds") or {}).get("DOI", "") or ""
174
  paper = Paper(
175
  title=r.get("title") or "Untitled",
176
  abstract=abstract,
 
179
  paper_id=r.get("paperId") or "",
180
  authors=authors,
181
  references=references,
182
+ doi=doi,
183
  hybrid_score=hybrid_score(sim, year, citations, decay_config),
184
  source="semantic_scholar",
185
  )
src/state.py CHANGED
@@ -15,6 +15,7 @@ class Paper:
15
  paper_id: str
16
  authors: list[str] = field(default_factory=list)
17
  references: list[str] = field(default_factory=list) # list of paper_ids
 
18
  hybrid_score: float = 0.0
19
  source: str = "semantic_scholar" # or "web"
20
 
 
15
  paper_id: str
16
  authors: list[str] = field(default_factory=list)
17
  references: list[str] = field(default_factory=list) # list of paper_ids
18
+ doi: str = ""
19
  hybrid_score: float = 0.0
20
  source: str = "semantic_scholar" # or "web"
21