Use this skill when the user wants to search for academic papers, analyze PDF files, extract metadata, or save papers to Zotero.
You are an academic research assistant.
Use this skill to:
Trigger this skill if the user:
You MUST choose the correct action:
search → find papersdownload → download PDFanalyze → extract metadata or full textarchive → save to Zoterosearch before download if no URL is providedanalyze to extract BibTeX before archivingThis skill provides a comprehensive solution for academic paper research and management. It allows users to search for papers across multiple engines, analyze PDF files to extract metadata, and archive papers to Zotero for easy reference.
| Situation | Action |
|---|---|
| Search for papers | Use search action with query parameter |
| Analyze PDF header | Use analyze action with pdf_path and analysis_type="header" |
| Analyze PDF full text | Use analyze action with pdf_path and analysis_type="fulltext" |
| Archive paper to Zotero | Use archive action with paper_info parameter |
Via ClawdHub (recommended):
clawdhub install academic-talon
Install Python dependencies:
pip install -r requirements.txt
Create a .env file in the skill directory with the following variables:
# Zotero API credentials
ZOTERO_API_KEY=your_zotero_api_key
ZOTERO_LIBRARY_ID=your_zotero_library_id
ZOTERO_LIBRARY_TYPE=user # or group
# Optional API keys for additional search engines
SEMANTIC_SCHOLAR_API_KEY=your_semantic_scholar_api_key # Optional
SERPAPI_KEY=your_serpapi_key # For Google Scholar
TAVILY_API_KEY=your_tavily_api_key # For Tavily
# GROBID API URL (default: http://localhost:8070/api)
GROBID_API_URL=http://localhost:8070/api
from skill import skill
# Search for papers on "hallucination"
result = skill.run({
"action": "search",
"query": "hallucination",
"limit": 5,
"source": "all"
})
print(result)
# Search papers with custom engine weights
result = skill.run({
"action": "search",
"query": "hallucination in AI",
"limit": 10,
"source": "all",
"engine_weights": {
"arxiv": 5,
"google_scholar": 3,
"semantic_scholar": 1,
"tavily": 1
}
})
print(result)
from skill import skill
# Download PDF from URL with custom filename
result = skill.run({
"action": "download",
"url": "https://example.com/paper.pdf",
"filename": "example_paper.pdf"
})
print(result)
# Download PDF with custom save directory
result = skill.run({
"action": "download",
"url": "https://example.com/paper.pdf",
"save_dir": "/path/to/pdf/library"
})
print(result)
# Download PDF with paper info for citation key generation
result = skill.run({
"action": "download",
"url": "https://example.com/paper.pdf",
"paper_info": {
"title": "Paper Title",
"authors": ["John Doe", "Jane Smith"],
"year": "2024"
}
})
print(result)
from skill import skill
# Analyze PDF header from local path
result = skill.run({
"action": "analyze",
"pdf_input": "/path/to/paper.pdf",
"analysis_type": "header"
})
print(result)
# Analyze PDF full text from URL
result = skill.run({
"action": "analyze",
"pdf_input": "https://example.com/paper.pdf",
"analysis_type": "fulltext"
})
print(result)
from skill import skill
# Archive paper to Zotero
result = skill.run({
"action": "archive",
"paper_info": {
"title": "Paper Title",
"authors": ["Author 1", "Author 2"],
"year": "2023",
"abstract": "Paper abstract",
"url": "https://example.com/paper",
"pdf_url": "https://example.com/paper.pdf",
"bibtex": "@article{...}"
}
})
print(result)
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
| action | string | Action to perform ("search", "download", "analyze", "archive") | Yes | "search" |
| query | string | Search query (for search action) | Yes (search) | "" |
| limit | integer | Number of results to return (for search action) | No | 10 |
| source | string | Search source ("all", "semantic_scholar", "arxiv", "google_scholar", "tavily") | No | "all" |
| engine_weights | object | Dictionary of engine weights (for search action) | No | {"arxiv": 5, "google_scholar": 3, "semantic_scholar": 1, "tavily": 1} |
| url | string | URL of the PDF file (for download action) | Yes (download) | "" |
| filename | string | Filename to save the PDF as (for download action) | No | None |
| save_dir | string | Directory to save the PDF in (for download action) | No | None |
| paper_info | object | Paper information (for download and archive actions) | No | {} |
| collection | string | Name of the collection to add the paper to (for archive action) | No | "openclaw" |
| pdf_input | string | Path to local PDF file or URL to PDF (for analyze action) | Yes (analyze) | "" |
| analysis_type | string | Type of analysis ("header", "fulltext") | No | "header" |
{
"success": true,
"action": "search",
"query": "hallucination",
"results": [
{
"title": "Paper Title",
"authors": ["Author 1", "Author 2"],
"year": "2023",
"abstract": "Paper abstract",
"url": "https://example.com/paper",
"pdf_url": "https://example.com/paper.pdf",
"source": "semantic_scholar"
}
]
}
{
"success": true,
"action": "download",
"url": "https://example.com/paper.pdf",
"pdf_path": "/path/to/downloaded/paper.pdf"
}
{
"success": true,
"action": "analyze",
"pdf_input": "/path/to/paper.pdf",
"analysis_type": "header",
"result": "@article{...}"
}
{
"success": true,
"action": "archive",
"result": {
"success": true,
"item_id": "ABC123",
"added_to_collection": true
}
}
The skill returns error messages in the following format:
{
"success": false,
"error": "Error message"
}
Common errors include:
from skill import skill
# Search for papers on "artificial intelligence"
result = skill.run({
"action": "search",
"query": "artificial intelligence",
"limit": 3,
"source": "arxiv"
})
# Print results
if result["success"]:
for i, paper in enumerate(result["results"]):
print(f"{i+1}. {paper['title']}")
print(f"Authors: {', '.join(paper['authors'])}")
print(f"Year: {paper['year']}")
print(f"URL: {paper['url']}")
print(f"PDF URL: {paper['pdf_url']}")
print()