Add firecrawl-research skill for the Firecrawl Research Index - #257
Open
rakshith48 wants to merge 1 commit into
Open
Add firecrawl-research skill for the Firecrawl Research Index#257rakshith48 wants to merge 1 commit into
rakshith48 wants to merge 1 commit into
Conversation
Adds a skill covering Firecrawl's Research Index: semantic paper search
over abstracts, canonical metadata lookup, question-directed retrieval of
full-text passages inside a paper, related-work expansion by co-citation
neighbourhood / citers / references, and search over GitHub issues, PRs,
discussions, and READMEs for implementation prior art. Scope stays on the
Research Index; web search and URL extraction remain with exa-search and
parallel-web.
The client is firecrawl.v2.FirecrawlClient rather than the top-level
Firecrawl wrapper, which eagerly builds a legacy v1 client and raises
ValueError("No API key provided") before issuing a request. The index
serves anonymous requests, so that would have made keyless use impossible.
The CLI owns retries outright: the SDK's internal loop is disabled
(max_retries=1) so it cannot multiply with this one, and 408, 429, 5xx,
and transport errors are retried within a single bounded budget that
honours Retry-After. Non-retryable failures exit 1 with a one-line message
instead of a traceback.
The skill documents the index's quiet-failure modes: an empty passages
array means no indexed full text rather than absence of the result, the
author/category/date filters are conjunctive over the semantic candidate
pool and silently return nothing, relevance scores are unstable enough
between calls that thresholding on an absolute value is unsafe, and
work-level deduplication needs shared DOI/PMID/PMCID rather than paperId,
which differs between a preprint and its published record.
Raises the firecrawl-py floor from >=4.9.0 to >=4.41.0. The Research Index
methods are absent from 4.9.0 and 4.20.0 and only appear in later releases,
so the previous floor cannot satisfy this skill.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
firecrawl-research, a skill covering Firecrawl's Research Index — a purpose-built paper index for research agents. Its distinguishing capability is question-directed passage retrieval: given a paper and a question, it returns the full-text passages that answer it, which is what lets an agent verify that a paper actually reports a method or result before citing it, instead of inferring from the abstract.Five subcommands, all Research Index endpoints:
search-papers,inspect-paper,read-paper,related-papers,search-github. Web search and URL extraction are deliberately out of scope and stay withexa-searchandparallel-web.Also raises the
firecrawl-pyfloor inpyproject.tomlfrom>=4.9.0to>=4.41.0. The dependency was already declared but had no consumer; the Research Index methods are absent from 4.9.0 and 4.20.0 and only appear in later releases, so the previous floor could not satisfy this skill. Verified by installing each version and introspecting the client.Type of change
Skills touched
How this was tested
Every command below was run, and all five subcommands were additionally executed against the live API with a real key (not mocked).
tests/_metawas confirmed green on the base branch before any change, so the run above is not masking a pre-existing failure.Live API runs (real
FIRECRAWL_API_KEYunless noted, responses carried real paper ids):search-paperssearch-papers --categories cs.LG --from-date --to-dateinspect-paper arxiv:1706.03762read-paper arxiv:1706.03762 --question ... -o file.jsonrelated-papers ... --mode citers/--mode referencespoolSize/truncatedreportedsearch-githubscverse/scanpy#350and other real hitssearch-paperswithFIRECRAWL_API_KEYunsetBehaviour documented in the skill was derived from those runs rather than from the docs, which caught four things the docs do not state:
from_date/to_date, not the RESTfrom/to, and takesauthors/categoriesas lists rather than strings.read-paperreturnssuccess: truewithpassages: []when the index holds metadata but no full text (pmid:34515826,pmcid:PMC13172344do this;arxiv:1706.03762does not). The script warns on stderr and the skill documents it as "no indexed full text", not "the paper does not say this".pageTypeandnumberare absent on README/repository hits fromsearch-github, so a direct subscript raises on the first such result.scoreis not safe to threshold on. The samesearch-papersquery returned a ~0.98 top score and, hours later, ~0.03 with a different top paper, no query or filter change. The skill documents scores as usable only for ordering within a single response.Reliability and keyless use
The top-level
Firecrawlwrapper cannot serve the index's anonymous access: it eagerly builds a legacy v1 client and raisesValueError: No API key providedbefore issuing a request. The script therefore usesfirecrawl.v2.FirecrawlClient, which constructs without a key. Keyless was verified end to end against the live index.Retries are owned in one place.
firecrawl-py4.41's HTTP layer runs its own loop over transport errors and502; left at its default that multiplies with the script's loop, so a persistent 502 would cost 4 x 3 = 12 requests with stacked sleeps. The client is built withmax_retries=1, making the script the sole retry owner, and it covers408,429,500,502,503,504and transport errors within one bounded budget, honouringRetry-After(delta-seconds and HTTP-date forms, capped so a pathological header cannot hang the run) and falling back to exponential backoff. Non-retryable failures exit1with a one-line stderr message rather than a traceback.Both are pinned by tests that drive the real objects rather than mocks: the client tests construct an actual
FirecrawlClientwith and without a key, and the 502 test drives the real SDK request path withrequests.getpatched, asserting exactlyMAX_ATTEMPTSHTTP requests. Reverting either fix fails them (3 != 1and12 != 4).Related issues and references
Checklist
Skill format
namefrontmatter match exactly.SKILL.md,references/, andscripts/— notests/directory and notest_*.pyfiles.SKILL.mdhas valid YAML frontmatter and a Markdown body.metadata.metadatais a block mapping, not single-line JSON, and scalar values are quoted where needed.metadata.openclawormetadata.hermesblock is a nested mapping, not a JSON string.metadata.versionexists, is quoted, and is bumped if an existing skill changed. (New skill, starts at"1.0"; no existing skill changed.)descriptionsays both what the skill does and when an agent should use it.Validation and tests
uv run skills-ref validate ./skills/firecrawl-researchpasses.tests/firecrawl-research/, and the[skills.firecrawl-research]entry is intests/skill-requirements.toml.Content and safety
compatibilityand declared inmetadata.openclaw.envVars.Security scan
scan_pr_skills.pyreports LOW, 0 high/critical (CI fails at HIGH). The analyzer is LLM-backed and its finding set varies slightly between runs; across runs the substantive items were:LLM_PROMPT_INJECTION— retrieved third-party text enters the agent context. Mitigated: SKILL.md carries an untrusted-data hazard section instructing the agent to quote and summarise but never follow embedded instructions. A re-scan recorded it as "explicitly and correctly mitigates this … informational residual risk only". Inherent to any retrieval skill.LLM_SUPPLY_CHAIN_ATTACK— unpinnedfirecrawl-py>=4.41.0. Not changed: an open lower bound matches the existing convention (exa-searchusesexa-py>=1.14.0). Happy to pin if you would rather.LLM_DATA_EXFILTRATION— the documenteddotenv -f .env run --setup step loads the whole.envinto the child environment. Not changed: this is the patternexa-searchalready documents, and the class AGENTS.md flags as a systematic false positive for a skill that reads its own key and calls its own service. Worth changing repo-wide if you disagree, rather than in one skill.LLM_HARMFUL_CONTENT(one run only) citedtemplates/*.mdandassets/*.mdas missing. The skill references no such paths —grepfinds none andtests/_metalink-checks every local link. This is the path-inference false positive AGENTS.md warns about.Notes for reviewers
Positioning against
paper-lookup. Deliberately complementary, and stated as such in this skill's routing:paper-lookupowns identifier resolution, exhaustive per-database coverage, and open-access full-text retrieval; this skill owns semantic search and passage-level verification. The documented fallback when passages are empty ispaper-lookup.-o/--outputmust follow the subcommand. It is declared on a shared parent parser rather than at the top level: declaring it in both places makes argparse silently reset it toNonewhen it appears before the subcommand, which would drop the destination file without an error. A test pins both the working placement and the loud rejection of the other.Attribution.
metadata.skill-authoris set toFirecrawl, following theexa-searchprecedent of attributing a vendor integration to the vendor. Change it if you would rather it readK-Dense Inc.Not verified / human follow-up
FIRECRAWL_API_KEYas a repository secret. Keyless does work — verified from a datacenter address — but the anonymous rate limit is low and shared across a runner's egress IP, so it is not a dependable CI path.Retry-Afterpaths use a fake exception carrying the SDK'sstatus_code/responseshape, because the live rate limit was never tripped. Two SDK internals are load-bearing and worth a glance if it restructures: the error classes are not exported from the package root (so the script keys off duck-typed attributes), andfirecrawl.v2.FirecrawlClientis a versioned rather than top-level import.plugin.jsonandpyproject.tomlboth remain2.65.0and stay in sync. Bump both together if a new skill should ship a release.firecrawl-pyfloor bump affects the project environment, not just this skill. Worth auv syncon your side to confirm nothing else in the repo depended on a pre-4.41 API. Nothing else imports the package today.docs/images/firecrawl-research.pngdiagram. Optional per AGENTS.md, and generating one needsOPENROUTER_API_KEY, which was not available.python tests/run_all.py --isolatedsweep was not run — only thefirecrawl-researchentry. The sweep needs CUDA/JDK/MATLAB toolchains for other skills.