{"id":"literature-review-agent","name":"literature-review-agent","summary":"PaperOrchestraパイプラインのステップ3(arXiv:2604.05018)。outline.json文献検索戦略を実行してください — ウェブ検索で候補論文を見つけ、Semantic Scholar(Levenshtein >70の曖昧なタイトルマッチ、時間的カットオフ、paperIdによるデデアップ)…","body":"# Literature Review Agent (Step 3)\n\nFaithful implementation of the Hybrid Literature Agent from PaperOrchestra\n(Song et al., 2026, arXiv:2604.05018, §4 Step 3, App. D.3, App. F.1 p.46).\n\n**Cost: ~20–30 LLM calls.** This is one of the two longest steps (the other is\nplotting). Wall-time floor is set by Semantic Scholar's 1 QPS verification\nlimit.\n\n## Inputs\n\n- `workspace/outline.json` — specifically `intro_related_work_plan` with the\n  Introduction search directions and the 2-4 Related Work methodology\n  clusters\n- `workspace/inputs/conference_guidelines.md` — used to derive `cutoff_date`\n- `workspace/inputs/idea.md`, `workspace/inputs/experimental_log.md` — for\n  framing the Intro and grounding the Related Work positioning\n\n## Outputs\n\n- `workspace/citation_pool.json` — verified Semantic Scholar metadata for\n  every paper that survived verification\n- `workspace/refs.bib` — BibTeX file generated from the verified pool\n- `workspace/drafts/intro_relwork.tex` — drafted Introduction and Related\n  Work sections, written into the template, with the rest of the template\n  preserved verbatim\n\n## Two-phase pipeline (App. D.3)\n\n```\nPHASE 1 — Parallel Candidate Discovery\n   For each search direction in introduction_strategy.search_directions:\n   For each limitation_search_query in each related_work cluster:\n     - Use the host's web search tool to discover up to ~10 candidate papers.\n     - Run up to 10 discovery queries in parallel (host-permitting).\n     - Collect (title, snippet, url) tuples — no verification yet.\n   → PRE-DEDUP before Phase 2 (see Step 1.5 below)\n\nPHASE 2 — Sequential Citation Verification (1 QPS, with cache)\n   For each candidate (after pre-dedup), sequentially:\n     0. Check s2_cache.json first (scripts/s2_cache.py --check).\n        If HIT: use cached response, skip live S2 call. No throttle needed.\n        If MISS: proceed with live request below.\n     1. Query Semantic Scholar by title:\n          GET https://api.semanticscholar.org/graph/v1/paper/search?query=<title>\n              &fields=title,abstract,year,authors,venue,externalIds&limit=5\n        (Public endpoint, no key. Throttle to 1 QPS for live requests only.)\n     2. Store the S2 response in cache: s2_cache.py --store.\n     3. Pick the top hit. Check Levenshtein title ratio against the original\n        candidate title. If ratio < 70: discard.\n     4. Bonus: if year and venue exactly align with hints, add a +5 point\n        match-quality bonus.\n     5. Require: abstract is non-empty.\n     6. Require: paper.year (or month if known) strictly predates cutoff_date.\n        Months default to day-1: e.g., \"October 2024\" → 2024-10-01.\n     7. If all checks pass, add to verified pool.\n   After all candidates are verified, dedup by Semantic Scholar paperId.\n```\n\nThe host agent does the LLM/web work; the deterministic helpers in `scripts/`\ndo the math.\n\n## Step-by-step\n\n### 0. Derive `cutoff_date`\n\nParse `conference_guidelines.md` for the submission deadline. The paper aligns\nresearch cutoff with venue submission deadline (App. D.1):\n\n| Venue | Cutoff |\n|---|---|\n| CVPR 2025 | Nov 2024 |\n| ICLR 2025 | Oct 2024 |\n| Other | One month before the stated submission deadline |\n\nEncode as `YYYY-MM-DD`. Months default to day-1 (e.g., `2024-10-01`).\n\n### 1. Phase 1: Parallel Candidate Discovery\n\nFrom `outline.json`:\n\n- All `introduction_strategy.search_directions` (3-5 queries)\n- For each cluster in `related_work_strategy.subsections`:\n  - The cluster's `sota_investigation_mission` becomes a search query\n  - All `limitation_search_queries` (1-3 each)\n\nFor each query, **use your host's web search tool** (e.g., `WebSearch` in\nClaude Code, `@web` in Cursor, the search tool in Antigravity). Collect the\ntop ~10 candidates per query: title, abstract snippet, source URL.\n\nIf your host supports parallel sub-tasks, fire up to 10 concurrent search\nqueries. If not, run sequentially — slower but functionally equivalent.\n\n#### Optional: Exa as a Phase 1 backend\n\nIf your host has no native web search, OR you want a research-paper-focused\nbackend with better signal-to-noise, you can use [Exa](https://exa.ai) via\nthe bundled `scripts/exa_search.py` helper. It is **opt-in** and reads\n`EXA_API_KEY` from the environment — the repo never commits a key.\n\n```bash\nexport EXA_API_KEY=\"your-key-here\"   # get one at https://dashboard.exa.ai/\npython skills/literature-review-agent/scripts/exa_search.py \\\n    --query \"Sparse attention long context transformers\" \\\n    --num-results 15 \\\n    --discovered-for \"related_work[2.1]\"\n```\n\nOutput is a normalized candidate list ready to merge into\n`raw_candidates.json`. Phase 2 verification (Semantic Scholar fuzzy match,\ncutoff, dedup) is unchanged. See `references/exa-search-cookbook.md` for\nthe full recipe, query patterns, cost estimates, and security notes.\n\n#### Optional: Tavily as a Phase 1 backend\n\nIf your host has no native web search, OR you want an LLM-optimized search\nbackend with high relevance scoring, you can use [Tavily](https://tavily.com)\nvia the bundled `scripts/tavily_search.py` helper. It is **opt-in** and reads\n`TAVILY_API_KEY` from the environment — the repo never commits a key.\n\n```bash\nexport TAVILY_API_KEY=\"tvly-your-key-here\"   # get one at https://app.tavily.com\npython skills/literature-review-agent/scripts/tavily_search.py \\\n    --query \"Sparse attention long context transformers\" \\\n    --num-results 15 \\\n    --academic \\\n    --discovered-for \"related_work[2.1]\"\n```\n\nOutput is a normalized candidate list ready to merge into\n`raw_candidates.json`. Phase 2 verification (Semantic Scholar fuzzy match,\ncutoff, dedup) is unchanged. See `references/tavily-search-cookbook.md` for\nthe full recipe, query patterns, cost estimates, and security notes.\n\nCombine all discovered candidates into a single working list. Tag each with\nthe originating query ID so you can later attribute it to \"intro\" vs\n\"related_work[i]\".\n\n### 1.5. Pre-dedup before Phase 2\n\n**Always run this before starting Phase 2.** Multiple search queries routinely\nreturn the same papers (e.g., \"Attention is All You Need\" appears in almost\nevery NLP discovery query). Verifying duplicates wastes 30-40% of S2 quota\nat 1 QPS.\n\n```bash\npython skills/literature-review-agent/scripts/pre_dedup_candidates.py \\\n    --in workspace/raw_candidates.json \\\n    --out workspace/deduped_candidates.json\n# Prints: \"150 candidates → 97 unique (53 duplicates removed)\"\n```\n\nUse `workspace/deduped_candidates.json` as input to Phase 2.\n\n### 2. Phase 2: Sequential Verification via Semantic Scholar (with cache)\n\nFor each candidate in `deduped_candidates.json`, in **sequential** order:\n\n**Step A — check cache first** (no S2 call, no throttle needed):\n```bash\npython skills/literature-review-agent/scripts/s2_cache.py \\\n    --cache workspace/cache/s2_cache.json \\\n    --check \"<candidate title>\"\n# exit 0 + prints JSON → use cached response, skip Step B\n# exit 1 → proceed to Step B\n```\n\n**Step B — live S2 request** (cache MISS only, throttle to 1 QPS):\n\n**Preferred:** use the bundled `scripts/s2_search.py` helper — it handles\nauth, retries, and 429 back-off automatically:\n\n```bash\npython skills/literature-review-agent/scripts/s2_search.py \\\n    --query \"<URL-decoded candidate title>\" --limit 5\n# If SEMANTIC_SCHOLAR_API_KEY is set the key is forwarded automatically.\n# If not, the public unauthenticated endpoint is used (≤1 QPS, still works).\n```\n\nCheck whether the key is configured before starting Phase 2:\n\n```bash\npython skills/literature-review-agent/scripts/s2_search.py --check-key\n```\n\n**Fallback:** if you prefer your host's URL fetch tool, GET:\n```\nhttps://api.semanticscholar.org/graph/v1/paper/search?query=<URL-encoded title>&limit=5&fields=title,abstract,year,authors,venue,externalIds\n```\nAdd header `x-api-key: <SEMANTIC_SCHOLAR_API_KEY>` if the env var is set.\nBe polite: ≤1 request per second for live requests. Cache hits are free.\n\n**Step C — store in cache** (after every successful live request):\n```bash\npython skills/literature-review-agent/scripts/s2_cache.py \\\n    --cache workspace/cache/s2_cache.json \\\n    --store \"<candidate title>\" \\\n    --response '<full S2 JSON response>'\n```\n\nFor the top hit:\n\n```bash\npython skills/literature-review-agent/scripts/levenshtein_match.py \\\n    --candidate \"Original candidate title\" \\\n    --found \"S2 returned title\"\n# prints integer 0-100. Discard if < 70.\n```\n\nThen check the temporal cutoff:\n\n```bash\npython skills/literature-review-agent/scripts/check_cutoff.py \\\n    --paper-year 2024 \\\n    --paper-month 9 \\\n    --cutoff 2024-10-01\n# exit 0 if strictly predates, exit 1 if not\n```\n\nIf both checks pass AND the abstract is non-empty, append the paper's full\nS2 metadata to the verified pool.\n\n### 3. Dedup and assemble the pool\n\nAfter all candidates are verified:\n\n```bash\npython skills/literature-review-agent/scripts/dedupe_by_id.py \\\n    --in raw_pool.json \\\n    --out workspace/citation_pool.json\n```\n\nThe dedupe script keys on `paperId` (Semantic Scholar's internal unique ID),\nfalling back to `externalIds.DOI`, then `externalIds.ArXiv`, then a\nnormalized title.\n\nThe script also computes and writes `min_cite_paper_count` =\n`floor(0.9 * len(papers))` — the minimum number of papers the writing step\nmust cite (the paper's ≥90% integration rule, App. D.3).\n\n**Immediately after dedupe_by_id.py**, validate and auto-fix the pool schema:\n\n```bash\npython skills/literature-review-agent/scripts/validate_pool.py \\\n    --pool workspace/citation_pool.json --fix\n# Catches and fixes authors-as-strings, reports missing required fields.\n# Must pass before proceeding to Step 4.\n```\n\n### 3.5. Cross-index verification (Crossref + OpenAlex)\n\nSemantic Scholar is one index and can return a plausible record for a paper\nthat does not exist, or attach wrong metadata. Re-check every S2-verified\npaper against two **independent** indices before building the bibliography —\nthis is the practical defense against hallucinated citations leaking in.\n\n```bash\n# Optional but recommended: a polite-pool email gives faster, more reliable\n# service. The repo never commits an address.\nexport PAPER_ORCHESTRA_MAILTO=\"you@example.com\"\n\npython skills/literature-review-agent/scripts/cross_verify.py \\\n    --pool workspace/citation_pool.json --inplace\n# Annotates each paper with a `cross_verification` field and writes\n# workspace/cross_verification_report.json.\n# exit 0 = all corroborated; exit 1 = WARN (something flagged or an index\n# was unreachable); exit 2 = usage error.\n```\n\nThis is a **WARN gate, not a hard gate** (like `validate_consistency.py`): it\nflags suspicious citations but does not block the pipeline or delete anything.\nReview the `low` and `conflict` tiers in the report:\n\n- `high` — corroborated by ≥1 external index → keep.\n- `medium` — corroborated but year disagrees → keep, spot-check the year.\n- `low` — not found in Crossref or OpenAlex → **review by hand**. Note that\n  arXiv-only preprints (no DOI) are a common benign cause; `low` means\n  \"could not corroborate,\" not \"fabricated.\" S2 already confirmed it exists.\n- `conflict` — pool DOI disagrees with the external DOI → likely wrong record.\n\nDrop only the entries you genuinely cannot corroborate, then re-run\n`dedupe_by_id.py` onward. If both indices are unreachable (offline), the script\ndegrades gracefully and the pipeline continues on S2 verification alone.\n\nSee `references/cross-index-verification.md` for the full rationale, confidence\ntiers, and the arXiv false-positive note.\n\n### 4. Build the BibTeX file\n\n```bash\npython skills/literature-review-agent/scripts/bibtex_format.py \\\n    --pool workspace/citation_pool.json \\\n    --out workspace/refs.bib\n```\n\nThe script generates citation keys deterministically from `firstauthor + year\n+ first significant word of title` (e.g., `vaswani2017attention`). It writes\nout only `@article` / `@inproceedings` / `@misc` entries — never invents\nfields. It also writes the canonical `bibtex_key` back into each paper record\nin `citation_pool.json`.\n\n**Immediately after bibtex_format.py**, sync keys in `intro_relwork.tex`:\n\n```bash\npython skills/literature-review-agent/scripts/sync_keys.py \\\n    --pool workspace/citation_pool.json \\\n    --tex  workspace/drafts/intro_relwork.tex \\\n    --inplace\n# Replaces every \\cite{agent_key} with \\cite{canonical_bibtex_key}.\n# Eliminates citation_coverage gate failures caused by key mismatch.\n```\n\nThese two steps replace the manual Python snippets that were previously\nrequired. The pipeline is now:\n\n```\ndedupe_by_id → validate_pool --fix → cross_verify --inplace → bibtex_format → sync_keys\n```\n\n### 5. Draft Introduction + Related Work\n\nThis is where you (the host agent) actually write text. Load the\n**verbatim Literature Review Agent prompt** at `references/prompt.md`.\nSubstitute the template placeholders:\n\n| Placeholder | Value |\n|---|---|\n| `intro_related_work_plan` | full JSON object from `outline.json` |\n| `project_idea` | contents of `idea.md` |\n| `project_experimental_log` | contents of `experimental_log.md` |\n| `citation_checklist` | the BibTeX keys from `refs.bib` |\n| `collected_papers` | list of `{key, title, abstract}` from `citation_pool.json` |\n| `paper_count` | `len(citation_pool.papers)` |\n| `min_cite_paper_count` | from `citation_pool.json` |\n| `cutoff_date` | the date you derived in Step 0 |\n\n**Also prepend the Anti-Leakage Prompt** from\n`../paper-orchestra/references/anti-leakage-prompt.md`.\n\nRun your LLM with the combined prompt against `template.tex`. The agent's\njob is to fill in the empty Introduction and Related Work sections of the\ntemplate **and leave everything else untouched**. Output: the full\n`template.tex` with those two sections filled. Save to\n`workspace/drafts/intro_relwork.tex`.\n\n### 5b. Append §2 to research_brief.md\n\nAfter `intro_relwork.tex` is drafted and before the citation coverage check,\nappend §2 to `workspace/research_brief.md` (see `skills/shared/research_brief_template.md`).\n\nTemplate:\n\n```markdown\n## §2 · Literature Landscape\n_Written by: literature-review-agent, Step 3_\n\n**What the literature says about the core claim:** <2-3 sentence synthesis>\n\n**Strongest prior work (must address in the paper):**\n- <bibtex_key>: <why this is the strongest comparator or predecessor>\n\n**Gaps confirmed by the literature:** <list>\n\n**Baseline comparisons — verification status:**\n| Baseline | In citation_pool? | Confidence tier |\n|---|---|---|\n\n**Related Work cluster coverage:**\n| Cluster | Papers found | Notes |\n|---|---|---|\n\n**Anything the section-writing agent should know:** <important context>\n```\n\nThis synthesises what was actually found — not what the outline assumed.\n\n### 6. Verify ≥90% citation coverage\n\n```bash\npython skills/literature-review-agent/scripts/citation_coverage.py \\\n    --tex workspace/drafts/intro_relwork.tex \\\n    --pool workspace/citation_pool.json\n# exit 0 if ≥90% of pool is cited; exit 1 otherwise\n```\n\nIf the gate fails, re-prompt the writing step explicitly listing the missing\nkeys and asking the agent to integrate them where contextually appropriate.\n\n## Critical rules from the prompt\n\nThese are excerpted from `references/prompt.md`. The host agent MUST honor\nthem on the writing call:\n\n- **Cite ONLY from `collected_papers`.** Never invent BibTeX keys, never\n  reference papers not in the pool.\n- **Cite at least `min_cite_paper_count` of them** in Intro + Related Work\n  combined.\n- **TIMELINE RULE**: Do not treat any papers published after `cutoff_date`\n  as prior baselines to beat. They are concurrent work only.\n- **EVALUATION RULE**: Do not claim our method beats / achieves SOTA over a\n  specific cited paper UNLESS that paper is explicitly evaluated against in\n  `experimental_log.md`. Frame other recent papers strictly as concurrent,\n  orthogonal, or conceptual work.\n- **Output format**: return the full code for the updated `template.tex`,\n  with the two empty sections (Introduction and Related Work) filled in,\n  and **all the other code** (packages, styles, other sections) **identical\n  to the original** template.tex.\n- Wrap output in ```` ```latex ... ``` ```` fences.\n- Do not change `\\usepackage[capitalize]{cleveref}` to `cleverref` (there is\n  no `cleverref.sty`).\n\n## Degraded mode (no web search)\n\nIf your host has no web search tool, switch to degraded mode:\n\n1. If the user has placed a pre-built `workspace/inputs/refs.bib` in the\n   workspace, load it directly into `workspace/refs.bib` and skip Phase 1\n   and Phase 2.\n2. Otherwise, emit `workspace/drafts/intro_relwork.tex` containing the\n   template with two TODO markers in the Intro and Related Work sections,\n   and tell the user the pipeline cannot complete Step 3 without web search.\n\n## Resources\n\n- `references/prompt.md` — verbatim Literature Review Agent prompt from App. F.1\n- `references/discovery-pipeline.md` — Phase 1 + Phase 2 explained in detail\n- `references/verification-rules.md` — Levenshtein cutoff, year alignment, dedup\n- `references/citation-density-rule.md` — the ≥90% integration rule\n- `references/s2-api-cookbook.md` — Semantic Scholar URLs, fields, rate limits\n- `references/cross-index-verification.md` — Crossref + OpenAlex corroboration, confidence tiers, arXiv false-positive note\n- `references/exa-search-cookbook.md` — optional Exa backend for Phase 1 (research-paper-focused web search)\n- `references/tavily-search-cookbook.md` — optional Tavily backend for Phase 1 (LLM-optimized web search)\n- `scripts/pre_dedup_candidates.py` — **NEW** dedup Phase 1 candidates before Phase 2 (saves 30-40% S2 quota)\n- `scripts/s2_cache.py` — **NEW** persistent S2 response cache (eliminates re-verification on re-runs)\n- `scripts/validate_pool.py` — **NEW** validate & auto-fix citation_pool.json schema (authors format)\n- `scripts/sync_keys.py` — **NEW** sync cite keys in .tex with canonical bibtex_keys after bibtex_format.py\n- `scripts/levenshtein_match.py` — fuzzy title match (ratio > 70)\n- `scripts/check_cutoff.py` — date cmp w/ month → day-1 default\n- `scripts/dedupe_by_id.py` — dedup verified pool by S2 paperId\n- `scripts/bibtex_format.py` — build refs.bib from JSON pool\n- `scripts/citation_coverage.py` — ≥90% citation coverage gate\n- `scripts/s2_search.py` — **NEW** Semantic Scholar title-search helper; reads `SEMANTIC_SCHOLAR_API_KEY` from env (optional — falls back to unauthenticated)\n- `scripts/exa_search.py` — optional Exa Phase 1 backend (reads `EXA_API_KEY` from env)\n- `scripts/tavily_search.py` — optional Tavily Phase 1 backend (reads `TAVILY_API_KEY` from env)\n- `scripts/crossref_client.py` — **NEW** Crossref title/DOI lookup for cross-index corroboration (no key; reads `CROSSREF_MAILTO` / `PAPER_ORCHESTRA_MAILTO`)\n- `scripts/openalex_client.py` — **NEW** OpenAlex title/DOI lookup for cross-index corroboration (no key; reads `OPENALEX_MAILTO` / `PAPER_ORCHESTRA_MAILTO`)\n- `scripts/cross_verify.py` — **NEW** cross-corroborate the S2-verified pool against Crossref + OpenAlex; flags hallucinated citations (WARN gate)\n- `skills/shared/research_brief_template.md` — **NEW** §2 schema; append after intro_relwork.tex is drafted","author":"@Ar9av","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/Ar9av/PaperOrchestra/tree/main/skills/literature-review-agent","license":"MIT","category":"review","lang":"en","tokens":4852,"stars":0,"calls30d":1,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[{"path":"references/citation-density-rule.md","size":2881,"sha256":"7f700d50c71259c3e480143bf1a8be7a16dd968bf3a8ebc5bdcb64304981f827"},{"path":"references/cross-index-verification.md","size":4556,"sha256":"be80aa1e59d5afb919fbe81fa5550bc7ed5521d0f33a57b24de5a84f34e76a78"},{"path":"references/discovery-pipeline.md","size":4892,"sha256":"639cff15d542239112b047fcbdbf34280600abb65cc4a0d60c3a6165203cd63c"},{"path":"references/exa-search-cookbook.md","size":9331,"sha256":"728b3cfc5ea6bbaf381d43aa0fc81a6bd5a7ce0ad3169d69a6afb100581f01b7"},{"path":"references/prompt.md","size":3294,"sha256":"6cd0eeef41b3650799a5052049cb0e17eef7818b438f137a3dcbbc276c56383b"},{"path":"references/s2-api-cookbook.md","size":4230,"sha256":"24af198bc7941bc9336883fcf789f8433961adf8d76998094b2593bac007d915"},{"path":"references/tavily-search-cookbook.md","size":10093,"sha256":"88bf3e26aebdc0599d23d7a1bd35d7851407bbd5ce7b561c18f1196c7095765f"},{"path":"references/verification-rules.md","size":5482,"sha256":"9a44f6982433268a16eddede7ca9b76ae264aac0a82ae2f43778059ce1fe1d05"},{"path":"scripts/bibtex_format.py","size":5325,"sha256":"d6face6a19b83d359a32a014c4aae409f07356e7f3f005f2d8736fe7f076a9ab"},{"path":"scripts/check_cutoff.py","size":2275,"sha256":"1665292067931a643fb4db6b5e9c5cebe7bc64b28602e16f4eb08bced3814b41"},{"path":"scripts/citation_coverage.py","size":3171,"sha256":"a8b1ff71e446e4613d742d5d33bf569d32169e23e194beba042692d874b9b175"},{"path":"scripts/crossref_client.py","size":6144,"sha256":"35f815abd73d7166fd6e14ea683d3b1f68137274ca5f84ead619faac95256e7e"},{"path":"scripts/cross_verify.py","size":12559,"sha256":"1429f6df4f108f43189efb50149065ea7e2db1121895199e6b0d5470c8a9ca1a"},{"path":"scripts/dedupe_by_id.py","size":3217,"sha256":"8914c63f1fa84de037eba452557385086ca139e4b92728feee87438bde20e390"},{"path":"scripts/exa_search.py","size":6028,"sha256":"c08221bd93e7160c0355007a2ded2780a3265a137f4cdc189e9c62d5496302be"},{"path":"scripts/levenshtein_match.py","size":2199,"sha256":"b8812dcb56af73b48576a19384831f4d946ac0db566da3533a57b926f1afbabc"},{"path":"scripts/openalex_client.py","size":6129,"sha256":"070ebc2d5e32749e84d90bdfdfbc759bd2ef0166d8a4a6495f8202c56b02aa26"},{"path":"scripts/pre_dedup_candidates.py","size":5032,"sha256":"6ea80ab167a9b16c7cc3ab49844e0e0586a8898b8aad91a3529b0b0985f25d33"},{"path":"scripts/s2_cache.py","size":3570,"sha256":"0501ab634341bc272940a04395e58127a507f8c332b2bc0b2ccf4af9c746dcb2"},{"path":"scripts/s2_search.py","size":7190,"sha256":"0722cbd28f8affa0d6aa75dafb6bd45221cd2b6378c4494df0e0ab9a8a3e6d95"},{"path":"scripts/sync_keys.py","size":4052,"sha256":"0d733d4089b7c4c5e3af08bb3b78c137ec22b1b7b8fdde86e039e0c39d889af2"},{"path":"scripts/tavily_search.py","size":6236,"sha256":"727773a0cf77594a805876ce7dbae0f9c40e817d2d7ddf603979eefea5894c3c"},{"path":"scripts/validate_pool.py","size":4892,"sha256":"ecfae907cfac2e203dab2544478c4411046c4b5d83e500c1eca43b75c39379e8"}],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[{"code":"net.endpoints","kind":"exfiltration","excerpt":"api.crossref.org, api.exa.ai, api.openalex.org, api.semanticscholar.org, api.tavily.com, app.tavily.com, arxiv.org, dashboard.exa.ai","message":"bundled scripts reach 11 external host(s)","severity":"warn"}],"scannedAt":"2026-08-22","hasScripts":true,"networkEndpoints":["api.crossref.org","api.exa.ai","api.openalex.org","api.semanticscholar.org","api.tavily.com","app.tavily.com","arxiv.org","dashboard.exa.ai","doi.org","exa.ai","tavily.com"]}}