Initial commit for research-lookup

This commit is contained in:
dfty
2026-01-29 22:14:58 +08:00
commit 198fbcca20
6 changed files with 2071 additions and 0 deletions

187
lookup.py Executable file
View File

@@ -0,0 +1,187 @@
#!/usr/bin/env python3
"""
Research Lookup Tool for Claude Code
Performs research queries using Perplexity Sonar Pro Search via OpenRouter.
"""
import os
import sys
import json
from typing import Dict, List, Optional
# Import the main research lookup class
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'scripts'))
from research_lookup import ResearchLookup
def format_response(result: Dict) -> str:
"""Format the research result for display."""
if not result["success"]:
return f"❌ Research lookup failed: {result['error']}"
response = result["response"]
citations = result["citations"]
sources = result.get("sources", [])
# Format the output for Claude Code
output = f"""🔍 **Research Results**
**Query:** {result['query']}
**Model:** {result['model']}
**Timestamp:** {result['timestamp']}
**Note:** Results prioritized by citation count, venue prestige, and author reputation
---
{response}
"""
# Display API-provided sources with venue/citation info
if sources:
output += f"\n📚 **Sources ({len(sources)}):**\n"
output += "_Prioritized by venue quality and citation impact_\n\n"
for i, source in enumerate(sources, 1):
title = source.get("title", "Untitled")
url = source.get("url", "")
date = source.get("date", "")
snippet = source.get("snippet", "")
# Format source entry with available metadata
date_str = f" ({date})" if date else ""
output += f"{i}. **{title}**{date_str}\n"
# Add venue indicator if detectable from URL
venue_indicator = _detect_venue_tier(url)
if venue_indicator:
output += f" 📊 Venue: {venue_indicator}\n"
if url:
output += f" 🔗 {url}\n"
if snippet:
output += f" _{snippet[:150]}{'...' if len(snippet) > 150 else ''}_\n"
output += "\n"
# Display extracted citations (DOIs, etc.)
if citations:
doi_citations = [c for c in citations if c.get("type") == "doi"]
url_citations = [c for c in citations if c.get("type") == "url"]
if doi_citations:
output += f"\n🔗 **DOI References ({len(doi_citations)}):**\n"
for i, citation in enumerate(doi_citations, 1):
output += f"{i}. DOI: {citation.get('doi', '')}{citation.get('url', '')}\n"
if url_citations:
output += f"\n🌐 **Additional URLs ({len(url_citations)}):**\n"
for i, citation in enumerate(url_citations, 1):
url = citation.get('url', '')
venue = _detect_venue_tier(url)
venue_str = f" [{venue}]" if venue else ""
output += f"{i}. {url}{venue_str}\n"
if result.get("usage"):
usage = result["usage"]
output += f"\n**Usage:** {usage.get('total_tokens', 'N/A')} tokens"
return output
def _detect_venue_tier(url: str) -> Optional[str]:
"""Detect venue tier from URL to indicate source quality."""
if not url:
return None
url_lower = url.lower()
# Tier 1 - Premier venues
tier1_indicators = {
"nature.com": "Nature (Tier 1)",
"science.org": "Science (Tier 1)",
"cell.com": "Cell Press (Tier 1)",
"nejm.org": "NEJM (Tier 1)",
"thelancet.com": "Lancet (Tier 1)",
"jamanetwork.com": "JAMA (Tier 1)",
"pnas.org": "PNAS (Tier 1)",
}
# Tier 2 - High-impact specialized
tier2_indicators = {
"neurips.cc": "NeurIPS (Tier 2 - Top ML)",
"icml.cc": "ICML (Tier 2 - Top ML)",
"openreview.net": "Top ML Conference (Tier 2)",
"aacrjournals.org": "AACR Journals (Tier 2)",
"ahajournals.org": "AHA Journals (Tier 2)",
"bloodjournal.org": "Blood (Tier 2)",
"jci.org": "JCI (Tier 2)",
}
# Tier 3 - Respected academic sources
tier3_indicators = {
"springer.com": "Springer",
"wiley.com": "Wiley",
"elsevier.com": "Elsevier",
"oup.com": "Oxford University Press",
"arxiv.org": "arXiv (Preprint)",
"biorxiv.org": "bioRxiv (Preprint)",
"medrxiv.org": "medRxiv (Preprint)",
"pubmed": "PubMed",
"ncbi.nlm.nih.gov": "NCBI/PubMed",
"ieee.org": "IEEE",
"acm.org": "ACM",
}
for domain, label in tier1_indicators.items():
if domain in url_lower:
return label
for domain, label in tier2_indicators.items():
if domain in url_lower:
return label
for domain, label in tier3_indicators.items():
if domain in url_lower:
return label
return None
def main():
"""Main entry point for Claude Code tool."""
# Check for API key
if not os.getenv("OPENROUTER_API_KEY"):
print("❌ Error: OPENROUTER_API_KEY environment variable not set")
print("Please set it in your .env file or export it:")
print(" export OPENROUTER_API_KEY='your_openrouter_api_key'")
return 1
# Get query from command line arguments
if len(sys.argv) < 2:
print("❌ Error: No query provided")
print("Usage: python lookup.py 'your research query here'")
return 1
query = " ".join(sys.argv[1:])
try:
# Initialize research tool
research = ResearchLookup()
# Perform lookup
print(f"🔍 Researching: {query}")
result = research.lookup(query)
# Format and output result
formatted_output = format_response(result)
print(formatted_output)
# Return success code
return 0 if result["success"] else 1
except Exception as e:
print(f"❌ Error: {str(e)}")
return 1
if __name__ == "__main__":
exit(main())