| """Analyze stage — deep technical analysis for core-track papers (mid tier). |
| |
| Capped at ``constants.analyze_cap`` papers per run (highest-relevance first) to bound cost. |
| """ |
|
|
| from __future__ import annotations |
|
|
| import sqlite3 |
|
|
| from wam.config import Config |
| from wam.llm import LLMClient |
| from wam.logging import get_logger |
| from wam.pipeline.schemas import PaperAnalysis |
| from wam.store import papers as ps |
|
|
| log = get_logger("pipeline.analyze") |
|
|
| SYSTEM = ("You are an expert reviewer of World Action Models (embodied/robot foundation " |
| "models, VLA, world models). Analyze the paper rigorously and skeptically. Always " |
| "write in English, regardless of the paper's language.\n\n" |
| "--- PROFILE ---\n{profile}") |
|
|
|
|
| def run(cfg: Config, client: LLMClient, conn: sqlite3.Connection, |
| limit: int | None = None) -> int: |
| cap = limit or int(cfg.get("constants.analyze_cap", 40)) |
| system = SYSTEM.format(profile=cfg.profile_text()) |
| todo = ps.needs_analysis(conn, limit=cap) |
| log.info("analyzing %d core papers (cap=%d)", len(todo), cap) |
| done = 0 |
| for row in todo: |
| user = f"Title: {row['title']}\n\nAbstract: {row['abstract'] or '(none)'}" |
| try: |
| a = client.complete_json("analyze", system, user, PaperAnalysis, |
| label="analyze", max_tokens=5000) |
| except Exception as e: |
| log.warning("analyze failed for %s: %s", row["id"], e) |
| continue |
| ps.set_analysis(conn, row["id"], a.model_dump_json()) |
| done += 1 |
| if done % 10 == 0: |
| conn.commit() |
| conn.commit() |
| log.info("analyzed %d papers", done) |
| return done |
|
|