Web research
Fred can call web_search and web_fetch to read the live internet. Off by default — enable at /settings. Once on, the agent decides when to use them; you don't type a slash command.
How it works
The two tools are registered alongside bash, view, grep, etc. The model picks them when the question depends on information newer than its training data, or when you paste a URL.
web_search— Tavily-backed search. Returns ranked results with title, URL, relevance score, and a short excerpt.web_fetch— Tavily-backed extract. Cleans up to 20 URLs in one call into concatenated markdown.
Calls go through api.fredcode.net — the CLI never holds a Tavily key. Billing happens server-side; the cost is reported back in a response header so the result panel shows the actual debit.
Enabling
Visit /settings and flip the Web research switch. A confirmation modal lists the per-call rates before you turn it on. Disable is one click — no modal.
While off, the agent gets a clear error if it tries to search; it falls back to its training knowledge and tells you to enable the toggle. No credits move.
Pricing
Per-call retail. Bills against the same credits balance as token usage.
| Action | Cost |
|---|---|
web_search · basic | $0.020 / call |
web_search · advanced | $0.040 / call |
web_fetch · basic | $0.020 per 5 URLs |
web_fetch · advanced | $0.040 per 5 URLs |
Tavily charges per credit ($0.008 PAYG); we mark up 2.5×, the same margin as token usage. URL counts are ceiled to the next 5: fetching 6 URLs bills as 2 batches.
See the pricing page for the breakdown alongside token rates.
Permission flow
Each call still goes through the same [y/n/a/d] permission panel as bash, with the cost estimate added to the header:
search "what's new in FastAPI 0.115?"
max_results: 5
~$0.020 (basic)
[y]es [n]o [a]lways for web_search [d]etailsPressing aallows that tool name for the rest of the session, so a research-heavy chat doesn't prompt twice. See permissions for the full set of approval modes.
Limits
- 100 KB byte capper call, enforced CLI-side. Larger pages are truncated with a marker so the model doesn't blow its context window. For a long doc, search for the specific section first.
- 20 URLs max per
web_fetchcall. - No constructed URLs. The model can only fetch URLs you typed in chat or that came back from a previous
web_search. Same exfiltration guardrail Claude Code uses. - Plan mode keeps both tools registered, but the system prompt drops the when to use them section. Web reads belong in act mode.
Failure modes
| Status | What happened | What the model sees |
|---|---|---|
403 | Toggle is off. | Error: web research is disabled. Enable at …/settings |
402 | Balance ≤ 0 (toggle is on). | Error: out of credits. Top up at …/billing |
429 | Rate-limited (Tavily or our IP gate). | Error: web_search HTTP 429: … |
5xx | Tavily failure. No debit; diagnostic row written. | Error: web_search HTTP 5xx: … |
Failed Tavily calls don't debit. We still record a row in web_usage_events with cost_billed_microcents=0 and an error_class field so we can monitor reliability.
Usage and receipts
Every successful call writes a row to web_usage_events and a debit to credits_ledger (kind='web_usage_debit'), idempotent on a Worker-generated request_id. The response headers carry the receipts:
| Header | Meaning |
|---|---|
x-fred-web-cost-microcents | What this call billed (0 for internal accounts). |
x-fred-web-credits | Tavily-side credits consumed. |
x-fred-balance-microcents | Balance after the debit. |
x-fred-request-id | Idempotency key — quote in support tickets. |
Telemetry
With opt-in telemetry on, every call emits three event kinds you can query off telemetry_events:
web_search— query length (not text), result count, top domain, depth, topic, billed microcents, balance after.web_fetch— URLs requested / succeeded / failed, per-URL bytes, depth, format, truncation flag.web_research_chain— fires once per iteration that contained ≥1 web call. Captures the search → fetch shape and summed cost so you can see whether the model used results well.
Query lengths are recorded; query strings are not. Set FRED_TELEMETRY_NO_TEXT=1 to nuke any text fields the writer might capture, or opt out of telemetry entirely with /telemetry off (persistent) or --no-telemetry (this session only).
Accounts with is_internal=true are toggle-on at the proxy and bill at zero. web_usage_events rows still land for analytics; credits_ledger stays untouched.
Where else to look
- Permissions — how the
[y/n/a/d]panel works, plus rules and--yolo. - Telemetry — opt-in shape, what fields are captured.
- Pricing — token + web rates side by side.