File size: 3,072 Bytes
2a79143 ad651e3 2a79143 6a63556 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | from typing import TypedDict, Optional
from dataclasses import dataclass, field
# ---------------------------------------------------------------------------
# Dataclasses — typed objects passed through the graph
# ---------------------------------------------------------------------------
@dataclass
class Paper:
title: str
abstract: str
year: int
citation_count: int
paper_id: str
authors: list[str] = field(default_factory=list)
references: list[str] = field(default_factory=list) # list of paper_ids
doi: str = ""
hybrid_score: float = 0.0
source: str = "semantic_scholar" # or "web"
@dataclass
class WebResult:
url: str
snippet: str
title: str
inferred_year: Optional[int] = None
hybrid_score: float = 0.0
source: str = "web"
@dataclass
class Claim:
text: str
source_title: str
source_year: int
confidence: str # "high" | "medium" | "low"
flagged: bool = False # True if contested or contradicted
@dataclass
class SessionContext:
prior_positions: list[str] = field(default_factory=list)
flagged_contradictions: list[str] = field(default_factory=list)
prior_queries: list[str] = field(default_factory=list)
@dataclass
class SessionUpdate:
position: str
query: str
claim_confidences: list[Claim] = field(default_factory=list)
contradictions_found: list[str] = field(default_factory=list)
# ---------------------------------------------------------------------------
# Verdict constants — used by Critic agent
# ---------------------------------------------------------------------------
class Verdict:
PASS = "PASS"
STALE = "STALE"
CONTRADICTED = "CONTRADICTED"
INSUFFICIENT = "INSUFFICIENT"
FORCED_PASS = "FORCED_PASS"
# ---------------------------------------------------------------------------
# LangGraph state — the single TypedDict shared across all agents
# ---------------------------------------------------------------------------
class ResearchState(TypedDict):
# --- Input ---
original_query: str
session_id: str
# --- Planner output ---
session_context: Optional[SessionContext]
sub_questions: list[str]
# --- Retriever output ---
retrieved_papers: list[Paper]
citation_graph: dict # {paper_id: [cited_paper_ids]}
web_results: list[WebResult]
# --- Critic output ---
critic_verdict: str # one of Verdict constants
critic_notes: str
rewritten_questions: list[str]
retry_count: int
# --- Synthesizer output ---
synthesized_position: str
claim_confidences: list[Claim]
session_update: Optional[SessionUpdate]
export_md: str # NEW v2 — full session as markdown
# --- Eval / config ---
decay_config: str # "none" | "linear" | "log"
calibration_bin: str # filled by critic for eval aggregation
latency_ms: float
paper_reliability_scores: dict # {paper_id: ReliabilityScore.__dict__} |