| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- """Pipeline 运行时配置 — 集中读取 settings,减少 pipeline 噪音。"""
- from __future__ import annotations
- from dataclasses import dataclass
- from typing import Any
- from .plan_helpers import effective_max_results, is_pinned_single_year
- from .search_plan import ResolvedSearchPlan
- @dataclass(frozen=True)
- class SearchRuntimeConfig:
- max_results: int
- recall_max: int
- recall_cap: int
- recall_wall: float
- rank_wall: float
- arxiv_fallback_wall: float
- proc_min: int
- proc_enabled: bool
- http_timeout_sec: float
- http_max_attempts: int
- openalex_timeout_sec: float
- dblp_timeout_sec: float | None = None
- @classmethod
- def from_settings(
- cls,
- settings: Any,
- plan: ResolvedSearchPlan,
- max_results: int | None = None,
- ) -> "SearchRuntimeConfig":
- mr = max(int(max_results or getattr(plan, "max_results", None) or 10), 5)
- mr = effective_max_results(plan, mr)
- recall_max = int(plan.recall_max_candidates or 24)
- try:
- recall_cap_setting = int(settings.papergraph_recall_max_candidates)
- except (TypeError, ValueError):
- recall_cap_setting = 24
- recall_cap = max(mr + 4, min(60, recall_cap_setting, recall_max))
- recall_wall = max(
- 10.0, min(180.0, float(getattr(settings, "papergraph_search_recall_wall_sec", 42.0)))
- )
- venue = (plan.venues[0] if plan.venues else None) or None
- if is_pinned_single_year(plan) and venue:
- recall_wall = max(recall_wall, 75.0)
- rank_wall = max(
- 10.0, min(120.0, float(getattr(settings, "papergraph_fine_rank_pipeline_wall_sec", 25.0)))
- )
- arxiv_fb_wall = max(
- 3.0,
- min(90.0, float(getattr(settings, "papergraph_search_arxiv_fallback_wall_sec", 15.0))),
- )
- try:
- proc_min = int(getattr(settings, "papergraph_proceedings_supplement_min_candidates", 8) or 8)
- except (TypeError, ValueError):
- proc_min = 8
- proc_enabled = bool(getattr(settings, "papergraph_proceedings_supplement_enabled", True))
- http_timeout = max(
- 2.0, min(60.0, float(getattr(settings, "papergraph_search_recall_http_timeout_sec", 12.0)))
- )
- try:
- http_max_attempts = int(settings.papergraph_search_http_max_attempts)
- except (TypeError, ValueError):
- http_max_attempts = 2
- http_max_attempts = max(1, min(3, http_max_attempts))
- openalex_timeout = 18.0
- dblp_timeout: float | None = None
- if is_pinned_single_year(plan) and venue:
- dblp_timeout = 55.0
- openalex_timeout = 45.0
- return cls(
- max_results=mr,
- recall_max=recall_max,
- recall_cap=recall_cap,
- recall_wall=recall_wall,
- rank_wall=rank_wall,
- arxiv_fallback_wall=arxiv_fb_wall,
- proc_min=proc_min,
- proc_enabled=proc_enabled,
- http_timeout_sec=http_timeout,
- http_max_attempts=http_max_attempts,
- openalex_timeout_sec=openalex_timeout,
- dblp_timeout_sec=dblp_timeout,
- )
- def execution_kwargs(self) -> dict[str, Any]:
- """HTTP/超时等执行参数,不混入用户约束。"""
- out: dict[str, Any] = {
- "http_timeout_sec": self.http_timeout_sec,
- "http_max_attempts": self.http_max_attempts,
- "openalex_timeout_sec": self.openalex_timeout_sec,
- }
- if self.dblp_timeout_sec is not None:
- out["dblp_timeout_sec"] = self.dblp_timeout_sec
- return out
|