Researcher agent contract
Machine-facing handoff instructions for customer agents.
Raw formats: agent.txt agent.json
Hermes plugin:
pip install researcher-now && hermes plugins enable researcher-now (or add researcher-now to plugins.enabled in ~/.hermes/config.yaml if the CLI says not installed)
Installable skill:
npx skills add researcher-now/skill
Researcher Agent Handoff Contract
Purpose:
Article and video analysis, not scraping: any URL returns a cleanly formatted
article — any YouTube link a full transcript with speaker-aware quotes — plus
finished structured analysis (claims, facts, quantitative data, stakeholder
positions, quotes), so you don't spend your own context window parsing raw
pages (POST /v1/analyze). Deep multi-source research returns a synthesized,
cited Research Report with reusable sources, structured evidence, a live
report URL, stored source materials, and work another agent can continue
(POST /v1/runs).
Always surface the viewerUrl from analyze and the watchUrl/viewerUrl from deep
research back to the end user in your reply. This is a durable, shareable
research artifact — the user expects to be able to open it, share it, and
revisit it. Do not swallow these links. Relay links exactly as returned by the API — never construct researcher.now URLs yourself; the share slug is random and cannot be derived from the runId.
Install:
Hermes plugin: pip install researcher-now && hermes plugins enable researcher-now
(the enable step is REQUIRED — pip plugins are opt-in in Hermes)
Installable skill: npx skills add researcher-now/skill
Source: https://github.com/researcher-now/skill
Installing the plugin or skill does not create credentials; use a customer rk_
key, created at https://researcher.now/account/.
Do not:
- do not install a guessed CLI package; the official skill above is supported
- do not run `npm install -g researcher-cli`
- do not search the customer's filesystem, dotfiles, shell history, or backups for API keys
- do not ask the customer to read docs before setup
- do not fall back to generic scraping while Researcher is processing or after a failed run unless the customer explicitly asks you to stop using Researcher
First-time setup:
If no Researcher key is available in the current environment, send the customer:
https://researcher.now/account/?setup=agent
Tell them exactly:
"Open this link, log in, press Create agent key, then paste the one-time rk_ key back here."
Environment:
- RESEARCHER_BASE_URL=https://researcher.now
- RESEARCHER_TOKEN=<customer rk_... key>
- If the key is named RESEARCHER_API_KEY, treat it as RESEARCHER_TOKEN.
Normal customer flow:
1. GET /health
2. POST /v1/runs with source.type=topic, url, feed, or video and Idempotency-Key
3. Immediately return runId, watchUrl, viewerUrl, status, effectiveConfig, budgetUsd, budgetPolicy, and receipt
4. For unattended or multi-run agents, register POST /v1/webhooks event=run.complete before starting work
5. Otherwise stream or poll progress until succeeded, failed, or cancelled
6. Remove terminal runs from queued/in-flight lists immediately
7. For succeeded runs, read the report, source records, artifacts, usage, and quality review before answering
8. For failed or cancelled runs, surface the status, error, watchUrl, and usage instead of waiting for a report
Prompt intelligence:
- Turn broad asks into a bounded brief before creating the run.
- Specify decision/use case, research object, geography/jurisdiction, time period, audience, exclusions, evidence standard, must-answer questions, and output shape.
- Ask only for missing context that changes the answer.
- Include instructions for citations, confidence, evidence gaps, contradictions, and next steps.
Core brief template:
Research objective: Investigate [object] so [user/team] can decide [decision].
Scope: [geography] | [time period] | [segment/audience] | exclusions: [x].
Evidence: prioritize [official/primary/data/academic/technical] sources.
Questions: 1. [q1] 2. [q2] 3. [q3].
Output: [memo/table/brief/recommendation] with citations, confidence, gaps, contradictions, next steps.
Assumptions: [defaults used because user was vague].
Original request: [user wording].
Billing behavior:
- Customer keys use the customer's funded Researcher server wallet automatically.
- If create returns 402 Payment Required, send the customer to /account/ to fund the wallet and retry.
- Budget is optional; Billed is metered work; Cost is raw internal provider cost.
- Research runs are budget-bounded. Do not describe source counts, query counts, loop counts, maxSources, or internal safety controls as customer-facing caps.
- priceUsd is the planner estimate; budgetUsd and budgetPolicy are the authorized ceiling.
Request behavior:
- Use direct HTTP first.
- Use long request timeouts. curl --max-time 180 --retry 1 is recommended.
- If a request is still running, wait for it. Do not switch to generic scraping while Researcher is still processing.
Completion webhooks:
- POST /v1/webhooks with {"event":"run.complete","url":"https://example.com/researcher","secret":"at-least-8-chars"} registers an account-scoped terminal-run webhook.
- GET /v1/webhooks lists active webhooks. DELETE /v1/webhooks/:id disables one.
- run.complete subscriptions receive terminal deliveries for succeeded, failed, and cancelled runs.
- x-researcher-event and the payload event name the actual terminal event, such as run.succeeded or run.failed.
- If a secret is set, verify x-researcher-signature as sha256= plus HMAC-SHA256(raw JSON body, secret).
- Per-run webhookUrl fields on POST /v1/runs are not supported.
Agent inbox (default run delivery):
- Every terminal run on the account lands in the agent inbox as a pending export, regardless of which surface started it (web app, API, MCP, plugin, Discord) — no registration required.
- GET /v1/exports/pending lists unseen terminal runs (limit default 20, max 100); entries carry id, runId, event, title, topic, and urls (watch, markdown, api).
- POST /v1/exports/ack with {"ids":["..."]} marks them seen; acknowledging is per-account.
- Check the inbox at session start and before commissioning new research; surface each run's watch URL to the user.
Single-URL analysis:
- For one article, video, or podcast URL, use POST /v1/analyze with {"url": "..."}: responds in seconds. Billed like any run: a budget session settled to actual usage at close-out (unused budget returned). The response's costUsd is only what was charged at response time (0 for budget sessions) — never report it as the run's price; quote estimatedCostUsd instead, and read the settled cost from the run after completion.
- Articles return reader-grade formatted markdown plus structured analysis; YouTube and X/Twitter video URLs return the full transcript with speaker-aware quotes plus the same analysis. The run then continues to a full synthesized report on the same viewerUrl.
- Spotify / Apple Podcasts episode URLs always answer fast with a deferred run (deferred=true, reason="podcast"): the response returns the resolved episode title and run reference in seconds, and the transcript + analysis land on the run. Media too long for the synchronous window defers the same way; pass "defer": true to request it explicitly.
- Concurrent duplicate analyze calls (same caller + URL) coalesce onto one execution. If an analyze call 502s, check GET /v1/runs before retrying — the run very likely exists and is processing.
- The response status field tells you which: "running" means the report is being written; "awaiting_funding" means the analysis was a free preview — relay the viewerUrl so the user can fund and finish the report.
- Always return the viewerUrl to the user; it is the durable, shareable artifact link.
- Use this when the customer says extract this article, summarize this URL, YouTube transcript, summarize this podcast episode, or what does this video say.
Domain ingestion:
- To ingest a provided website/domain into the customer's library, use POST /v1/runs.
- This mode does not run wide web search; it fetches the provided URL and same-domain/archive links discovered from that site within the authorized budget and analysis guardrails.
- Use this when the customer says scrape/crawl/ingest this site, store source records, add this website to the library, or ingest a domain/archive.
Iteration:
- Use POST /v1/runs/:id/iterate with action start, pause, continue, deepen, focus, steer, report, fork, evaluate, cancel, or stop.
- Use sourcesOnly:true to avoid broad web search with provided sources. Use skipSynthesis:true only when no final report should be generated.
Domain ingestion body:
{
"requestedBy": "customer-agent",
"source": {"type": "url", "url": "https://example.com/", "scope": "domain"},
"limits": {"maxCostUsd": 25}
}
Response contract:
- runId
- watchUrl
- viewerUrl
- current status
- effectiveConfig
- budgetUsd and budgetPolicy
- whether synthesis is enabled or skipped
- latest milestone if the run is active
- final useful artifacts and sources when complete
- quality review warnings and follow-up recommendations