Real IMAP connection via imapflow library: - Connects to IMAP server (IMAPFlow, TLS on port 993) - Fetches recent messages (configurable limit, default 20) - Extracts: from, fromEmail, subject, date, snippet (200 chars) - Thread-to-contact matching (PRD §6.1): 1. Match sender email against persons table 2. If no person match, extract domain and match against company.website 3. Returns matchedCompany + matchedPerson for each email - Audit-logged (action: crm.mailsync:imap) - Zod validated (host, port, user, password, folder, limit) - 502 on IMAP connection failure with detail - 400 on validation failure Tested: invalid creds → 502 'IMAP connection failed', missing host → 400
6.2 KiB
Executable File
name, version, author, contact, description, metadata
| name | version | author | contact | description | metadata | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| aminer-deep-search | 2.0.0 | AMiner | report@aminer.cn | Activate this skill when the user wants deep, multi-round academic paper collection for a survey or literature review. The host model (the model running this skill) drives the loop itself: it expands queries, judges relevance, snowballs backward references, and decides when to stop. The bundled scripts are pure tool commands that call documented AMiner Open Platform endpoints and print JSON tool results only — no extra LLM configuration is needed. Use this skill for broad topic exploration, survey bibliography construction, and collecting hundreds of candidate papers with AMiner IDs and titles. Not intended for single-paper lookup or lightweight recommendations; use aminer-free-academic or aminer-daily-paper for those. |
|
AMiner Deep Search
Host-model-driven survey paper collection. You (the model reading this) are the controller: run the tool scripts, read their JSON output, judge relevance yourself, and iterate until the collection target is met.
Scope
- Use for: survey bibliography collection (hundreds of papers), keyword expansion, backward-citation snowballing.
- Do not use for: single-paper lookup or Q&A (route to
aminer-free-academic), personalized recommendations (route toaminer-daily-paper).
Pre-flight
- Check the key without printing it:
[ -z "${AMINER_API_KEY:-}" ] && echo "AMINER_API_KEY missing" || echo "AMINER_API_KEY exists"
If missing, stop and ask the user to set AMINER_API_KEY (console: https://open.aminer.cn/open/board?tab=control). Never print the key.
- Confirm the
topicand thetarget-size(default 400). If your round plan is estimated to cost ¥5 or more, tell the user the estimate and get confirmation before starting.
Tools
Both scripts live in scripts/ under this skill directory. They print exactly one JSON document to stdout (the tool result); diagnostics and a [cost] line go to stderr. They never score relevance — that is your job.
scripts/aminer_api.py — AMiner API calls
| Subcommand | Endpoint | Price |
|---|---|---|
search --query Q [--size 20] [--year YYYY] [--order n_citation|year] [--max-pages 3] |
GET /api/paper/search/pro + free paper/info enrichment |
¥0.01/page |
qa-search [--query "natural language question"] [--topic-high '[["termA","termB"],["termC"]]'] [--size 20] [--year-from Y] [--year-to Y] [--citation-sort] |
POST /api/paper/qa/search (always use_topic=true; the backend ignores query when use_topic=false) + free enrichment |
¥0.05/call |
info --ids id1 id2 ... |
POST /api/paper/info (batched ≤100 ids) |
Free |
references --ids id1 id2 ... [--per-seed 20] |
GET /api/paper/relation per seed + free enrichment |
¥0.10/seed |
Output shape: search/qa-search/info print [{id, title, year?, venue?, abstract_slice?}]; references additionally includes source_paper_ids (which seeds cited the paper). Seeds themselves are excluded from references output.
scripts/paper_set.py — cross-round state file (no network)
State file defaults to outputs/paper_set.json relative to the working directory.
# Merge kept results (pipe the filtered JSON array in), dedupe by id
python3 scripts/aminer_api.py search --query "..." | python3 scripts/paper_set.py add
# → {"added": N, "duplicates": M, "total": T}
python3 scripts/paper_set.py stats # totals, expanded_seeds, by_year
python3 scripts/paper_set.py mark-expanded --ids id1 id2 # record snowballed seeds
python3 scripts/paper_set.py export -o outputs/final_papers.json
add also accepts --ids id1 id2 ... for bare IDs. Items carrying source_paper_ids (from references) automatically mark those seeds as expanded.
If you want to filter before adding, read the search output first, then pipe only the kept items:
printf '%s' '[{"id":"...","title":"..."}]' | python3 scripts/paper_set.py add
Round Protocol (core)
Round 0 — plan
- Derive 4–8 seed queries from the topic: synonyms, subfields, method names, datasets/benchmarks, common English abbreviations.
- Estimate rounds and cost (searches ≈ ¥0.01–0.05 each, references ≈ ¥0.10/seed). If the estimate is ≥¥5, confirm with the user first.
Each round (default budget: 12 rounds), five fixed steps
- Search: run 1–4
search/qa-searchcalls from the pending query queue. Prefersearch(cheaper); useqa-searchwhen the query is a natural-language question. - Filter & add: read the stdout results, judge relevance to the topic yourself, and pipe only the kept items into
paper_set.py add. Never add papers you consider off-topic. - Check: run
statsto see the total and this round's increment. - Snowball: from this round's relevant additions pick ≤5 strong seeds (highly relevant, ranked high under
--order n_citation, not inexpanded_seeds) and runreferences --ids .... Filter the output for relevance, then add it. Runmark-expandedfor seeds that yielded nothing addable. - Decide: choose the next move —
- a search returned <5 results or poor quality → replace it with a reformulated query (max 2 variants per direction, then switch to snowballing);
- references are yielding many relevant papers → keep snowballing from fresh seeds;
- reached
target-size, or results are exhausted, or 2 consecutive rounds added <5 papers → terminate.
Wrap-up
Run export, then report: final paper count, total cost (sum the [cost] stderr lines), and the output path.
Rules
- Never fabricate paper IDs or titles; only cite data actually returned by the tools.
- Free first: metadata always comes from the free
paper/info(the scripts already do this); never call the paidpaper/detailfor bulk metadata. - Keep the raw tool output out of your final answer; report counts and the exported file path instead.
- Never print or log
AMINER_API_KEY. - If AMiner returns fewer papers than the target, report the real count instead of inventing papers.