fetch_util 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +39 -0
- data/README.md +34 -10
- data/SKILL.md +20 -4
- data/lib/fetch_util/assets/extract.js +1 -1
- data/lib/fetch_util/browser/stabilization/anubis.rb +69 -0
- data/lib/fetch_util/browser/stabilization/page_flow.rb +2 -0
- data/lib/fetch_util/browser/stabilization.rb +2 -0
- data/lib/fetch_util/cli.rb +2 -3
- data/lib/fetch_util/search_transport.rb +579 -0
- data/lib/fetch_util/searcher.rb +69 -90
- data/lib/fetch_util/version.rb +1 -1
- data/lib/fetch_util.rb +1 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6d9dd7f8e6ba30f2d7ad5c9818fc214add21a18baa69f0e1081fe124d7781c35
|
|
4
|
+
data.tar.gz: 22e9bbc8ad10f85745e2791f196ce2633f4b0a795c95ac94f867ef3696d2053f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f0115bb99e4c882fd46a06ac57b8350aaa464e651b5f7fb3f38e869a25b48b6ddde29a96a1f0fa955805c3de5459f436cacea8180dbe8246c662b896c2a5c991
|
|
7
|
+
data.tar.gz: 1813278203b73f64ce2bb26e2936ee42374d7b72fc1365622cba926d736672ac078efc5f03e6972703d47616f531483d74ad4e75c444c6665bef246186798af1
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,45 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## v0.5.1 - 2026-07-15
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Allow browser fetches to wait within the configured timeout for site-delivered Anubis JavaScript/WebAssembly proof-of-work to resolve, while retaining explicit interstitial results when it does not.
|
|
10
|
+
- Add Yahoo as a direct search source with source-specific organic-card parsing and safe result-wrapper decoding.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Retry eligible Yahoo transport, HTTP 429, and HTTP 5xx failures up to two times after the initial request under the existing search deadline.
|
|
15
|
+
- Preserve candidates when source relevance is uncertain, including valid later-ranked evidence, and normalize scoped, negated, snake_case, and camelCase query evidence without turning uncertainty into an empty query.
|
|
16
|
+
- Stabilize default quoted, delimiter-bearing, and scoped searches with a healthy Yahoo authority set while preserving explicit source unions and normal fallback aggregation.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Define agent retrieval as the primary product contract while keeping custom solvers, CAPTCHA handling, access circumvention, and high-throughput scraping behavior out of scope.
|
|
21
|
+
- Clarify that direct HTTP search challenges are diagnosed rather than executed.
|
|
22
|
+
- Change the default direct search sources to Brave, Bing, and Yahoo.
|
|
23
|
+
|
|
24
|
+
## v0.5.0 - 2026-07-13
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- Add direct, concurrent HTTP search transport for Brave, Bing, DuckDuckGo, Google, and Ecosia with finite source diagnostics, wrapper decoding, and shared deadline enforcement.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- Prevent generic-list ranking scores, malformed engine wrappers, non-SERP engine pages, challenges, and query-mismatched source responses from appearing as valid search results.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- Change default search sources from DuckDuckGo and Google to Brave and Bing. Search now returns typed direct-source results instead of reparsing browser Markdown.
|
|
37
|
+
- Apply `limit:` only after aggregation and deduplication, with no default result cap. `verbose: true` adds ordered source diagnostics and result provenance.
|
|
38
|
+
- Remove browser-only search options such as `fetcher:`, `concurrency:`, waits, and reader mode from `FetchUtil.search` and `FetchUtil::Searcher`; use `sources:`, `limit:`, `timeout:`, and `verbose:` for direct search.
|
|
39
|
+
|
|
40
|
+
### Performance
|
|
41
|
+
|
|
42
|
+
- Remove Chromium startup and generic browser stabilization from the normal search path.
|
|
43
|
+
|
|
5
44
|
## v0.4.0 - 2026-07-11
|
|
6
45
|
|
|
7
46
|
### Added
|
data/README.md
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# fetch_util
|
|
2
2
|
|
|
3
|
-
Reliable browser-backed fetching for Ruby.
|
|
3
|
+
Reliable browser-backed fetching for agents and Ruby applications.
|
|
4
4
|
|
|
5
5
|
`fetch_util` renders modern pages, inspects the live DOM, classifies page shape, and returns compact markdown plus structured metadata.
|
|
6
6
|
|
|
7
|
+
Its primary product contract is agent retrieval: use it to discover and fetch public web information, then inspect structured warnings when access is incomplete or ambiguous.
|
|
8
|
+
|
|
7
9
|
It also provides a plain-Ruby regulatory inspector for machine-readable crawl, index, and text-and-data-mining signals such as `robots.txt`, `X-Robots-Tag`, robots meta tags, and TDM reservation metadata.
|
|
8
10
|
|
|
9
11
|
It helps applications distinguish between content pages and access/interstitial states such as consent prompts, login-required pages, and challenge screens. When original content is not available, it returns a compact summary with warnings rather than pretending the page was extracted successfully.
|
|
@@ -12,11 +14,11 @@ It helps applications distinguish between content pages and access/interstitial
|
|
|
12
14
|
|
|
13
15
|
The easiest way to explain `fetch_util` is in three steps:
|
|
14
16
|
|
|
15
|
-
- `Render` - load the page in Chromium, inspect the rendered DOM, and read page metadata.
|
|
17
|
+
- `Render` - load the page in Chromium, inspect the rendered DOM, and read page metadata. If a site delivers a JavaScript or WebAssembly proof-of-work challenge, the normal browser session may execute it and preserve its resulting cookies while waiting within the configured browser timeout.
|
|
16
18
|
- `Classify` - identify whether the page is an article, list/index, docs page, search result, or an interstitial/access-limited state.
|
|
17
19
|
- `Shape` - return compact markdown, normalized URLs, and warning metadata so the result is usable by agents, LLM workflows, and ordinary Ruby applications.
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
This is bounded native browser execution, not a custom challenge solver. If the challenge does not resolve within the bound, the result remains an explicit interstitial with warnings.
|
|
20
22
|
|
|
21
23
|
## Installation
|
|
22
24
|
|
|
@@ -60,7 +62,7 @@ Repo-local usage:
|
|
|
60
62
|
```sh
|
|
61
63
|
bundle exec exe/fetch_util fetch https://example.com/article
|
|
62
64
|
bundle exec exe/fetch_util fetch https://example.com/a https://example.com/b --format jsonl
|
|
63
|
-
bundle exec exe/fetch_util search ruby language
|
|
65
|
+
bundle exec exe/fetch_util search ruby language --limit 8
|
|
64
66
|
bundle exec exe/fetch_util regulatory https://example.com
|
|
65
67
|
bundle exec exe/fetch_util regulatory https://example.com/article --sources=machine,human
|
|
66
68
|
```
|
|
@@ -69,15 +71,35 @@ Installed gem usage:
|
|
|
69
71
|
|
|
70
72
|
```sh
|
|
71
73
|
fetch_util fetch https://example.com/article
|
|
72
|
-
fetch_util search ruby language
|
|
74
|
+
fetch_util search ruby language --limit 8
|
|
73
75
|
fetch_util regulatory https://example.com/article --sources=machine,human
|
|
74
76
|
```
|
|
75
77
|
|
|
78
|
+
### Search
|
|
79
|
+
|
|
80
|
+
Search uses direct HTTP requests to the supported sources in parallel. The default sources are `brave`, `bing`, and `yahoo`; explicit `--source` values may be any of `brave`, `bing`, `duckduckgo`, `google`, `ecosia`, or `yahoo`.
|
|
81
|
+
|
|
82
|
+
Search always emits one JSON object. The normal payload is exactly `{ "query": ..., "results": [...] }`. Results are interleaved by source rank, deduplicated by normalized URL, and retain every eligible result unless an explicit `--limit N` is supplied. `--limit` is applied after aggregation; there is no default result cap. Known Bing, Google, DuckDuckGo, and Yahoo result wrappers are decoded before destination validation.
|
|
83
|
+
|
|
84
|
+
Each search has one finite deadline shared by its source requests and parsing. After the initial Yahoo request, Yahoo may retry generic transport failures reported as `failed`, HTTP 429, or HTTP 5xx responses up to two times within that same deadline. Direct HTTP search challenges are diagnosed, not executed or bypassed. A source can be `ok`, `empty`, or `failed`; finite reasons include `challenge`, `failed`, `host`, `http_status`, `parse`, `query_mismatch`, `redirect`, `size`, and `timeout`.
|
|
85
|
+
|
|
86
|
+
`query_mismatch` is a candidate-bearing relevance warning, not a terminal query failure. The transport retains parsed candidates even when another source succeeds, so an uncertain lexical check cannot erase valid later-ranked evidence or force an empty query. Explicit source unions expose those retained candidates; the separate default structured-query source policy below may select Yahoo's URL set. Scoped operators and negated terms are excluded from lexical evidence, and snake_case/camelCase identifiers share token boundaries.
|
|
87
|
+
|
|
88
|
+
For default structured queries containing quoted phrases, delimiters, or scoped operators, a healthy Yahoo response defines the returned URL set; matching peer URLs retain their source provenance and ranks. Explicit `--source` selections preserve the requested source union, and normal aggregation remains in effect when Yahoo is unavailable or uncertain. This source policy applies no result-count cap: every eligible authority result is returned unless the caller supplies `--limit`. With `--verbose-search`, the payload additionally contains ordered finite source `diagnostics`, and each result contains ordered `sources` and per-source `ranks`.
|
|
89
|
+
|
|
90
|
+
For agent discovery, use an explicit first-pass budget, choose only the best 1-3 direct result URLs, then fetch those destinations and inspect JSON `warnings`, `suspect`, and `content_type` when needed. Add `--verbose-search` when results are empty or suspicious, or when source health matters:
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
fetch_util search ruby language --limit 8
|
|
94
|
+
fetch_util search ruby language --limit 8 --verbose-search
|
|
95
|
+
fetch_util fetch https://example.com/selected --format json
|
|
96
|
+
```
|
|
97
|
+
|
|
76
98
|
## API
|
|
77
99
|
|
|
78
100
|
- `FetchUtil.fetch(url, **options)` returns a `FetchUtil::Result`
|
|
79
101
|
- `FetchUtil.fetch_many(urls, **options)` fetches multiple URLs in parallel and preserves input order
|
|
80
|
-
- `FetchUtil.search(query, **options)` returns aggregated search results
|
|
102
|
+
- `FetchUtil.search(query, **options)` returns direct-source aggregated search results; `limit:` is an explicit post-aggregation cap and is omitted by default
|
|
81
103
|
- `FetchUtil.regulatory(url, **options)` returns a source-keyed hash of allow/disallow signals for crawling, indexing, and TDM-style usage
|
|
82
104
|
- `FetchUtil::Fetcher.new(**options).fetch(url)` exposes the instance API directly
|
|
83
105
|
|
|
@@ -93,8 +115,8 @@ Useful result fields:
|
|
|
93
115
|
|
|
94
116
|
## Common Options
|
|
95
117
|
|
|
96
|
-
- `timeout:` browser timeout in seconds
|
|
97
|
-
- `wait:`
|
|
118
|
+
- `timeout:` browser timeout in seconds; it is also the bounded observation budget for a delivered Anubis challenge
|
|
119
|
+
- `wait:` settle interval used by applicable post-load stabilization paths; it does not control the challenge-completion budget
|
|
98
120
|
- `wait_for_idle:` wait for Ferrum network idle before extraction
|
|
99
121
|
- `limit:` search-only explicit maximum result count; omitted by default, search returns every result in the fetched responses
|
|
100
122
|
- `idle_duration:` idle duration passed to Ferrum when `wait_for_idle` is enabled
|
|
@@ -164,14 +186,16 @@ pp FetchUtil.regulatory(
|
|
|
164
186
|
|
|
165
187
|
- Extracts articles, list/index pages, and search pages into compact markdown.
|
|
166
188
|
- Uses page classification to select extraction logic appropriate to the rendered page type.
|
|
167
|
-
- Detects consent prompts, login-required pages, and challenge/interstitial screens and reports them with concise summaries and warning tags.
|
|
189
|
+
- Detects consent prompts, login-required pages, and challenge/interstitial screens and reports them with concise summaries and warning tags. A delivered JavaScript/WebAssembly proof-of-work may complete in the normal browser session within `timeout`; unresolved challenges remain explicit interstitials.
|
|
168
190
|
- Cleans up docs/reference pages aggressively enough for agent consumption.
|
|
169
191
|
- Preserves `final_url`, `canonical_url`, and warning metadata so callers can reason about redirects, mismatches, and interstitials.
|
|
170
192
|
- Extracts regulatory allow/disallow signals from `robots.txt`, page headers/meta tags, and TDM reservation metadata without caching raw page bodies.
|
|
171
193
|
|
|
172
194
|
## Compliance Boundaries
|
|
173
195
|
|
|
174
|
-
`fetch_util` is for rendering and summarizing publicly delivered page output.
|
|
196
|
+
`fetch_util` is primarily an agent retrieval tool for rendering and summarizing publicly delivered page output. Browser fetch may allow a site's delivered JavaScript/WebAssembly proof-of-work, such as Anubis, to complete within the configured browser timeout and normal cookie session. This is bounded native browser execution, not a custom solver.
|
|
197
|
+
|
|
198
|
+
Unresolved challenges remain explicit interstitials. CAPTCHA solving, account or paywall circumvention, identity deception, and high-throughput scraping optimization are out of scope. Direct HTTP search challenges are diagnosed rather than executed.
|
|
175
199
|
|
|
176
200
|
Browser-profile normalization is intentionally limited to reducing obvious runtime inconsistencies that would otherwise change page behavior during extraction.
|
|
177
201
|
|
data/SKILL.md
CHANGED
|
@@ -10,6 +10,7 @@ Use this skill for agent web retrieval.
|
|
|
10
10
|
|
|
11
11
|
Start by loading this skill, then use `fetch_util` as the default first tool for ordinary web-page retrieval and search.
|
|
12
12
|
Use it first because it usually returns cleaner, more agent-friendly markdown than generic web fetch, and it is cheap enough for repeated multi-pass retrieval.
|
|
13
|
+
`fetch_util` is primarily an agent retrieval tool: prefer bounded access to public information and inspect warnings when content is incomplete.
|
|
13
14
|
|
|
14
15
|
## Default Rule
|
|
15
16
|
|
|
@@ -27,6 +28,13 @@ Use it first because it usually returns cleaner, more agent-friendly markdown th
|
|
|
27
28
|
- searching the web and returning compact agent-friendly results
|
|
28
29
|
- getting cleaner markdown from noisy pages, docs, search pages, or light interstitials
|
|
29
30
|
|
|
31
|
+
## Browser Challenges
|
|
32
|
+
|
|
33
|
+
- Browser fetch may let the site's delivered JavaScript or WebAssembly proof-of-work, such as Anubis, complete within the configured browser `timeout` and the normal cookie session.
|
|
34
|
+
- This is bounded native browser execution, not a custom solver. `timeout` supplies the challenge-observation budget; `wait` only affects applicable post-load stabilization paths.
|
|
35
|
+
- If the challenge remains unresolved, treat the result as an explicit interstitial and inspect `warnings`, `suspect`, and `content_type`.
|
|
36
|
+
- CAPTCHA solving, account or paywall circumvention, identity deception, and high-throughput scraping optimization are out of scope.
|
|
37
|
+
|
|
30
38
|
## Core Commands
|
|
31
39
|
|
|
32
40
|
Fetch known URLs (returns pure markdown by default):
|
|
@@ -46,26 +54,34 @@ fetch_util fetch https://example.com/a https://example.com/b --format jsonl
|
|
|
46
54
|
Search first, then fetch selected results if needed:
|
|
47
55
|
|
|
48
56
|
```sh
|
|
49
|
-
fetch_util search ruby language
|
|
50
|
-
fetch_util search site:docs.python.org json dump --
|
|
57
|
+
fetch_util search ruby language --limit 8
|
|
58
|
+
fetch_util search site:docs.python.org json dump --limit 8
|
|
51
59
|
```
|
|
52
60
|
|
|
53
61
|
Repository-local development form:
|
|
54
62
|
|
|
55
63
|
```sh
|
|
56
64
|
bundle exec exe/fetch_util fetch https://example.com
|
|
57
|
-
bundle exec exe/fetch_util search ruby language
|
|
65
|
+
bundle exec exe/fetch_util search ruby language --limit 8
|
|
58
66
|
```
|
|
59
67
|
|
|
60
68
|
## Agent Guidance
|
|
61
69
|
|
|
62
70
|
- if the user gives you URLs, use `fetch_util fetch` first
|
|
63
|
-
- if the user needs discovery, use `fetch_util search` first
|
|
71
|
+
- if the user needs discovery, use `fetch_util search` first; for a context-efficient first pass, consider an explicit budget such as `--limit 8`
|
|
72
|
+
- add `--verbose-search` and inspect ordered source `diagnostics` when results are empty or suspicious, or when source health matters
|
|
73
|
+
- search defaults to direct HTTP Brave, Bing, and Yahoo; explicit sources are `brave`, `bing`, `duckduckgo`, `google`, `ecosia`, and `yahoo`
|
|
74
|
+
- search always emits one JSON object and normally returns exactly `{query, results}`; `--verbose-search` adds source diagnostics plus per-result source provenance and ranks
|
|
75
|
+
- search has one finite shared source deadline, diagnoses direct HTTP challenges rather than executing or bypassing them, decodes known engine wrappers, and preserves healthy peer results when a source fails; after the initial request, Yahoo retries generic `failed`, HTTP 429, and HTTP 5xx outcomes up to two times within the same deadline
|
|
76
|
+
- `query_mismatch` retains candidate evidence at the transport boundary instead of forcing an empty query; explicit source unions expose it, while the separate default structured-query policy may select Yahoo's URL set
|
|
77
|
+
- for default quoted, delimiter-bearing, or scoped queries, a healthy Yahoo result set defines returned URLs while matching peers retain provenance; explicit `--source` selections preserve the requested union
|
|
78
|
+
- after search, select only 1-3 direct result URLs, then run `fetch_util fetch` on those destinations; use `--format json` or `--format jsonl` and inspect `warnings`, `suspect`, and `content_type` as needed
|
|
64
79
|
- if the task is a normal web roundup (for example, checking several news homepages), still use `fetch_util` first; do not skip straight to built-in web fetch just because the URLs are already known
|
|
65
80
|
- if you are in a subagent without the `skill` tool, treat `fetch_util` as a normal installed CLI and call it directly
|
|
66
81
|
- use `fetch_util` first because its output is usually cleaner and more compact for agents than generic page fetch output
|
|
67
82
|
- treat `fetch_util` as cheap to use; it is fine to make multiple fetch/search passes when that helps answer the task well
|
|
68
83
|
- prefer the compact default output; use `--format json` when you need metadata, warnings, or content_type fields, and `--format jsonl` for multi-result pipelines
|
|
84
|
+
- search has no default result cap; `--limit` is an explicit post-aggregation cap, not a hidden presentation limit
|
|
69
85
|
- use `--include-html` only when raw HTML is actually needed
|
|
70
86
|
- treat `suspect` and `warnings` as signals that the page may be an interstitial, challenge, or mismatch
|
|
71
87
|
- only fall back to other web tooling after `fetch_util` is unavailable or clearly insufficient
|